Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc2cb61219 | ||
|
|
c538fd8960 | ||
|
|
659f6fb690 | ||
|
|
1be9e9e75f | ||
|
|
9040e02025 | ||
|
|
8b0ea750d8 | ||
|
|
64bc12db06 | ||
|
|
0893bd4b54 | ||
|
|
4b23c779d3 | ||
|
|
249b930602 | ||
|
|
6727fa8e8f | ||
|
|
a0b7db0a70 | ||
|
|
03c4974c9f | ||
|
|
6f9b357473 | ||
|
|
d1d32b6292 | ||
|
|
47aafc7948 | ||
|
|
267c7b81c3 | ||
|
|
6e46152e4c | ||
|
|
34f9eeff2c | ||
|
|
f7ace4dfe9 | ||
|
|
0443d5e3d5 | ||
|
|
a28cb3f424 | ||
|
|
2c3b076b58 | ||
|
|
b3cd0b9349 | ||
|
|
5ef13239da | ||
|
|
0c16b2f104 | ||
|
|
707aa7f570 | ||
|
|
be8193e235 | ||
|
|
8e1f586d4f | ||
|
|
ad190d8952 | ||
|
|
40bde84648 | ||
|
|
a697ccc923 | ||
|
|
65508782c6 | ||
|
|
7bc82ab318 | ||
|
|
eca59dc67b | ||
|
|
497103bdb6 |
@@ -1,13 +1,5 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.16.12
|
||||
|
||||
- 修复 label 控件文字显示问题
|
||||
- 增强报错日志输出
|
||||
- 增加实时帧率显示
|
||||
- 首选项增加预览画面和投影最大帧率设置,移除用户状态和工作区帧率记忆
|
||||
- 优化某些性能
|
||||
|
||||
## v0.16.11
|
||||
|
||||
- 增加 shift 切换缩放倍数
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.16.0</Version>
|
||||
<UseWPF>true</UseWPF>
|
||||
|
||||
@@ -7,7 +7,6 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Threading;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SFMLRenderer
|
||||
{
|
||||
@@ -20,14 +19,6 @@ namespace SFMLRenderer
|
||||
SetActive(false);
|
||||
_timer.Tick += (s, e) => DispatchEvents();
|
||||
_timer.Start();
|
||||
|
||||
SetVisible(false);
|
||||
|
||||
var handle = SystemHandle;
|
||||
var exStyle = User32.GetWindowLong(handle, User32.GWL_EXSTYLE) | User32.WS_EX_LAYERED;
|
||||
User32.SetWindowLong(handle, User32.GWL_EXSTYLE, exStyle);
|
||||
User32.SetLayeredWindowAttributes(handle, 0, byte.MaxValue, User32.LWA_ALPHA);
|
||||
|
||||
RendererCreated?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.16.6</Version>
|
||||
<UseWPF>true</UseWPF>
|
||||
@@ -23,8 +20,4 @@
|
||||
<PackageReference Include="SFML.Net" Version="2.6.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Win32Natives\Win32Natives.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -14,14 +14,6 @@ namespace Spine.Exporters
|
||||
/// </summary>
|
||||
public abstract class BaseExporter : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 进度回调函数
|
||||
/// </summary>
|
||||
/// <param name="total">任务总量</param>
|
||||
/// <param name="done">已完成量</param>
|
||||
/// <param name="promptText">需要设置的进度提示文本</param>
|
||||
public delegate void ProgressReporterHandler(float total, float done, string promptText);
|
||||
|
||||
/// <summary>
|
||||
/// 日志器
|
||||
/// </summary>
|
||||
@@ -64,9 +56,14 @@ namespace Spine.Exporters
|
||||
|
||||
/// <summary>
|
||||
/// 可选的进度回调函数
|
||||
/// <list type="number">
|
||||
/// <item><c>total</c>: 任务总量</item>
|
||||
/// <item><c>done</c>: 已完成量</item>
|
||||
/// <item><c>progressText</c>: 需要设置的进度提示文本</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public ProgressReporterHandler? ProgressReporter { get => _progressReporter; set => _progressReporter = value; }
|
||||
protected ProgressReporterHandler? _progressReporter;
|
||||
public Action<float, float, string>? ProgressReporter { get => _progressReporter; set => _progressReporter = value; }
|
||||
protected Action<float, float, string>? _progressReporter;
|
||||
|
||||
/// <summary>
|
||||
/// 背景颜色
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace Spine.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0} {1}, {2}", _format, output, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Spine.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0} {1}, {2}", _format, output, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Spine.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to save frame {0}, {1}", savePath, ex.Message);
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.V21
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.V21
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.V21
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.V21
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.V34
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.V34
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.V34
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.V34
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.V35
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.V35
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.V35
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.V35
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.V36
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.V36
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.V36
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.V36
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.V37
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.V37
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.V37
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.V37
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Spine.Implementations.V38
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Spine.Implementations.V38
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ namespace Spine.Implementations.V38
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace Spine.Implementations.V38
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.V40
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.V40
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.V40
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.V40
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.V41
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.V41
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.V41
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.V41
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Spine.Implementations.V42
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load atlas '{atlasPath}'");
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Spine.Implementations.V42
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonBinary(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace Spine.Implementations.V42
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_skeletonData = new SkeletonJson(_atlas).ReadSkeletonData(skelPath);
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ namespace Spine.Implementations.V42
|
||||
catch (Exception ex)
|
||||
{
|
||||
_atlas.Dispose();
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load skeleton file {skelPath}");
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.16.11</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -269,7 +269,7 @@ namespace Spine
|
||||
|
||||
if (hit && LogHitSlots)
|
||||
{
|
||||
_logger.Info("Hit ({0}): [{1}]", self.Name, hitSlotName);
|
||||
_logger.Debug("Hit ({0}): [{1}]", self.Name, hitSlotName);
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Spine
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Warn("Failed to detect version for skel {0}, try all available versions", skelPath);
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ namespace Spine
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
throw new InvalidDataException($"Failed to load spine with version '{version}'");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>2.1.25</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.4.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.5.51</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.6.53</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.7.94</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.8.99</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.0.64</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.1.54</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -6,10 +6,7 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.2.74</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -43,8 +43,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpineRuntime35", "SpineRunt
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpineRuntime34", "SpineRuntimes\SpineRuntime34\SpineRuntime34.csproj", "{348605F7-3FF4-1DE0-4B91-7AEFE7BC5C55}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Win32Natives", "Win32Natives\Win32Natives.csproj", "{48864874-7307-950E-A667-62BB66357C62}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -107,10 +105,6 @@ Global
|
||||
{348605F7-3FF4-1DE0-4B91-7AEFE7BC5C55}.Debug|x64.Build.0 = Debug|x64
|
||||
{348605F7-3FF4-1DE0-4B91-7AEFE7BC5C55}.Release|x64.ActiveCfg = Release|x64
|
||||
{348605F7-3FF4-1DE0-4B91-7AEFE7BC5C55}.Release|x64.Build.0 = Release|x64
|
||||
{48864874-7307-950E-A667-62BB66357C62}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{48864874-7307-950E-A667-62BB66357C62}.Debug|x64.Build.0 = Debug|x64
|
||||
{48864874-7307-950E-A667-62BB66357C62}.Release|x64.ActiveCfg = Release|x64
|
||||
{48864874-7307-950E-A667-62BB66357C62}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using Microsoft.Win32;
|
||||
using NLog;
|
||||
using Win32Natives;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.ViewModels.MainWindow;
|
||||
using SpineViewer.Views;
|
||||
using System.Collections.Frozen;
|
||||
@@ -15,7 +14,6 @@ using System.IO.Pipes;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using SpineViewer.Extensions;
|
||||
|
||||
namespace SpineViewer
|
||||
{
|
||||
@@ -35,8 +33,8 @@ namespace SpineViewer
|
||||
#endif
|
||||
|
||||
public const string AutoRunFlag = "--autorun";
|
||||
private const string MutexName = $"__{AppName}_Instance__";
|
||||
private const string PipeName = $"_{AppName}_Pipe__";
|
||||
private const string MutexName = "__SpineViewerInstance__";
|
||||
private const string PipeName = "__SpineViewerPipe__";
|
||||
|
||||
public static readonly string ProcessPath = Environment.ProcessPath;
|
||||
public static readonly string ProcessDirectory = Path.GetDirectoryName(Environment.ProcessPath);
|
||||
@@ -60,16 +58,13 @@ namespace SpineViewer
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += (s, e) =>
|
||||
{
|
||||
_logger.Debug(e.ExceptionObject.ToString());
|
||||
_logger.Fatal("Unhandled exception: {0}", e.ExceptionObject);
|
||||
MessagePopupService.Error(e.ExceptionObject.ToString());
|
||||
};
|
||||
TaskScheduler.UnobservedTaskException += (s, e) =>
|
||||
{
|
||||
_logger.Debug(e.Exception.ToString());
|
||||
_logger.Fatal("Unobserved task exception: {0}", e.Exception.Message);
|
||||
_logger.Trace(e.Exception.ToString());
|
||||
_logger.Error("Unobserved task exception: {0}", e.Exception.Message);
|
||||
e.SetObserved();
|
||||
MessagePopupService.Error(e.Exception.ToString());
|
||||
};
|
||||
|
||||
// 单例模式加 IPC 通信
|
||||
@@ -135,7 +130,7 @@ namespace SpineViewer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to pass command line args to existed instance, {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -196,7 +191,7 @@ namespace SpineViewer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to process arguments, {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -217,10 +212,9 @@ namespace SpineViewer
|
||||
|
||||
private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
_logger.Debug(e.Exception.ToString());
|
||||
_logger.Fatal("Dispatcher unhandled exception: {0}", e.Exception.Message);
|
||||
_logger.Trace(e.Exception.ToString());
|
||||
_logger.Error("Dispatcher unhandled exception: {0}", e.Exception.Message);
|
||||
e.Handled = true;
|
||||
MessagePopupService.Error(e.Exception.ToString());
|
||||
}
|
||||
|
||||
public bool AutoRun
|
||||
@@ -237,7 +231,7 @@ namespace SpineViewer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to query autorun registry key, {0}", ex.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -265,7 +259,7 @@ namespace SpineViewer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to set autorun registry key, {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -349,7 +343,7 @@ namespace SpineViewer
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to switch language to {0}, {1}", value, ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -366,13 +360,14 @@ namespace SpineViewer
|
||||
{
|
||||
Resources.MergedDictionaries.Add(new() { Source = new(uri, UriKind.Relative) });
|
||||
Resources.MergedDictionaries.Add(new() { Source = new("Resources/Theme.xaml", UriKind.Relative) });
|
||||
Current.MainWindow.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
Current.MainWindow.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(Current.MainWindow).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
_skin = value;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to switch skin to {0}, {1}", value, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using SkiaSharp;
|
||||
using SFML.Graphics;
|
||||
using SFML.System;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -7,31 +9,29 @@ using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Extensions
|
||||
{
|
||||
public static class WpfExtension
|
||||
{
|
||||
public static SFML.Graphics.FloatRect ToFloatRect(this Rect self)
|
||||
public static FloatRect ToFloatRect(this Rect self)
|
||||
{
|
||||
return new((float)self.X, (float)self.Y, (float)self.Width, (float)self.Height);
|
||||
}
|
||||
|
||||
public static SFML.System.Vector2f ToVector2f(this Size self)
|
||||
public static Vector2f ToVector2f(this Size self)
|
||||
{
|
||||
return new((float)self.Width, (float)self.Height);
|
||||
}
|
||||
|
||||
public static SFML.System.Vector2u ToVector2u(this Size self)
|
||||
public static Vector2u ToVector2u(this Size self)
|
||||
{
|
||||
return new((uint)self.Width, (uint)self.Height);
|
||||
}
|
||||
|
||||
public static SFML.System.Vector2i ToVector2i(this Size self)
|
||||
public static Vector2i ToVector2i(this Size self)
|
||||
{
|
||||
return new((int)self.Width, (int)self.Height);
|
||||
}
|
||||
@@ -60,18 +60,6 @@ namespace SpineViewer.Extensions
|
||||
return wb;
|
||||
}
|
||||
|
||||
public static void SetWindowTextColor(this Window self, Color color)
|
||||
{
|
||||
var hwnd = new WindowInteropHelper(self).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
public static void SetWindowCaptionColor(this Window self, Color color)
|
||||
{
|
||||
var hwnd = new WindowInteropHelper(self).Handle;
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, color.R, color.G, color.B);
|
||||
}
|
||||
|
||||
//public static void SaveToFile(this BitmapSource bitmap, string path)
|
||||
//{
|
||||
// var ext = Path.GetExtension(path)?.ToLowerInvariant();
|
||||
|
||||
@@ -73,22 +73,6 @@ namespace SpineViewer.Models
|
||||
|
||||
#endregion
|
||||
|
||||
#region 预览画面首选项
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _renderSelectedOnly;
|
||||
|
||||
[ObservableProperty]
|
||||
private HitTestLevel _hitTestLevel;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _logHitSlots;
|
||||
|
||||
[ObservableProperty]
|
||||
private uint _maxFps = 30;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 程序选项
|
||||
|
||||
public RelayCommand Cmd_SelectAutoRunWorkspaceConfigPath => _cmd_SelectAutoRunWorkspaceConfigPath ??= new(() =>
|
||||
@@ -106,10 +90,16 @@ namespace SpineViewer.Models
|
||||
private AppSkin _appSkin;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _wallpaperView;
|
||||
private bool _renderSelectedOnly;
|
||||
|
||||
[ObservableProperty]
|
||||
private uint _wallpaperMaxFps = 30;
|
||||
private HitTestLevel _hitTestLevel;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _logHitSlots;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _wallpaperView;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _closeToTray;
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace SpineViewer.Models
|
||||
|
||||
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);
|
||||
|
||||
@@ -34,6 +34,8 @@ namespace SpineViewer.Models
|
||||
|
||||
public bool FlipY { get; set; } = true;
|
||||
|
||||
public uint MaxFps { get; set; } = 30;
|
||||
|
||||
public float Speed { get; set; } = 1f;
|
||||
|
||||
public bool ShowAxis { get; set; } = true;
|
||||
|
||||
@@ -4,8 +4,9 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Win32Natives
|
||||
namespace SpineViewer.Natives
|
||||
{
|
||||
/// <summary>
|
||||
/// dwmapi.dll 包装类
|
||||
@@ -23,15 +24,15 @@ namespace Win32Natives
|
||||
[DllImport("dwmapi.dll")]
|
||||
private static extern int DwmSetWindowAttribute(IntPtr hwnd, uint dwAttribute, ref uint pvAttribute, int cbAttribute);
|
||||
|
||||
public static bool SetWindowCaptionColor(IntPtr hwnd, byte r, byte g, byte b)
|
||||
public static bool SetWindowCaptionColor(IntPtr hwnd, Color color)
|
||||
{
|
||||
int c = r | (g << 8) | (b << 16);
|
||||
int c = color.R | (color.G << 8) | (color.B << 16);
|
||||
return 0 == DwmSetWindowAttribute(hwnd, DWMWA_CAPTION_COLOR, ref c, sizeof(uint));
|
||||
}
|
||||
|
||||
public static bool SetWindowTextColor(IntPtr hwnd, byte r, byte g, byte b)
|
||||
public static bool SetWindowTextColor(IntPtr hwnd, Color color)
|
||||
{
|
||||
int c = r | (g << 8) | (b << 16);
|
||||
int c = color.R | (color.G << 8) | (color.B << 16);
|
||||
return 0 == DwmSetWindowAttribute(hwnd, DWMWA_TEXT_COLOR, ref c, sizeof(uint));
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Win32Natives
|
||||
namespace SpineViewer.Natives
|
||||
{
|
||||
/// <summary>
|
||||
/// gdi32.dll 包装类
|
||||
@@ -7,7 +7,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Win32Natives
|
||||
namespace SpineViewer.Natives
|
||||
{
|
||||
/// <summary>
|
||||
/// shell32.dll 包装类
|
||||
@@ -7,7 +7,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace Win32Natives
|
||||
namespace SpineViewer.Natives
|
||||
{
|
||||
/// <summary>
|
||||
/// user32.dll 包装类
|
||||
@@ -316,7 +316,7 @@ namespace Win32Natives
|
||||
workerw = FindWindowEx(progman, IntPtr.Zero, "WorkerW", null);
|
||||
}
|
||||
|
||||
Debug.WriteLine($"HWND(WorkerW): 0x{workerw:x8}");
|
||||
Debug.WriteLine($"HWND(WorkerW): {workerw:x8}");
|
||||
return workerw;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<s:String x:Key="Str_Tool">Tools</s:String>
|
||||
<s:String x:Key="Str_Download">Download</s:String>
|
||||
<s:String x:Key="Str_Help">Help</s:String>
|
||||
<s:String x:Key="Str_DownloadFFmpeg">Go to download FFmpeg</s:String>
|
||||
<s:String x:Key="Str_Diagnostics">Diagnostics Info</s:String>
|
||||
<s:String x:Key="Str_Abount">About</s:String>
|
||||
<s:String x:Key="Str_Experiment">Experimental Features</s:String>
|
||||
@@ -124,8 +123,6 @@
|
||||
<s:String x:Key="Str_MaxFpsTooltip">Maximum frame rate of the preview. Set to 0 for no limit.</s:String>
|
||||
<s:String x:Key="Str_PlaySpeed">Playback Speed</s:String>
|
||||
<s:String x:Key="Str_WallpaperView">Wallpaper View</s:String>
|
||||
<s:String x:Key="Str_WallpaperMaxFps">Max FPS of Wallpaper View</s:String>
|
||||
<s:String x:Key="Str_WallpaperMaxFpsTooltip">Maximum frame rate of the wallpaper view. Set to 0 for no limit.</s:String>
|
||||
<s:String x:Key="Str_RenderSelectedOnly">Render Selected Only</s:String>
|
||||
<s:String x:Key="Str_HitTestLevel">Hit Test Accuracy Level</s:String>
|
||||
<s:String x:Key="Str_LogHitSlots">Output Hit Test Slot Names</s:String>
|
||||
@@ -143,9 +140,6 @@
|
||||
<s:String x:Key="Str_ForwardFastTooltip">Forward 10 Frames</s:String>
|
||||
<s:String x:Key="Str_FullScreenTooltip">Window/Fullscreen; F11</s:String>
|
||||
|
||||
<!-- 日志框下方附加信息 -->
|
||||
<s:String x:Key="Str_RealTimeFps">Real-time FPS: {0:F1}/{1:F1}</s:String>
|
||||
|
||||
<!-- 弹窗文本 -->
|
||||
<s:String x:Key="Str_OK">OK</s:String>
|
||||
<s:String x:Key="Str_Cancel">Cancel</s:String>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<s:String x:Key="Str_Tool">ツール</s:String>
|
||||
<s:String x:Key="Str_Download">ダウンロード</s:String>
|
||||
<s:String x:Key="Str_Help">ヘルプ</s:String>
|
||||
<s:String x:Key="Str_DownloadFFmpeg">FFmpeg をダウンロードしに行く</s:String>
|
||||
<s:String x:Key="Str_Diagnostics">診断情報</s:String>
|
||||
<s:String x:Key="Str_Abount">バージョン情報</s:String>
|
||||
<s:String x:Key="Str_Experiment">実験機能</s:String>
|
||||
@@ -124,8 +123,6 @@
|
||||
<s:String x:Key="Str_MaxFpsTooltip">プレビュー画面の最大フレームレート。0 に設定すると制限なし。</s:String>
|
||||
<s:String x:Key="Str_PlaySpeed">再生速度</s:String>
|
||||
<s:String x:Key="Str_WallpaperView">壁紙表示</s:String>
|
||||
<s:String x:Key="Str_WallpaperMaxFps">壁紙ビューの最大FPS</s:String>
|
||||
<s:String x:Key="Str_WallpaperMaxFpsTooltip">壁紙ビューの最大フレームレート。0に設定すると制限がなし。</s:String>
|
||||
<s:String x:Key="Str_RenderSelectedOnly">選択のみレンダリング</s:String>
|
||||
<s:String x:Key="Str_HitTestLevel">ヒットテスト精度レベル</s:String>
|
||||
<s:String x:Key="Str_LogHitSlots">ヒットテスト結果のスロット名を出力</s:String>
|
||||
@@ -143,9 +140,6 @@
|
||||
<s:String x:Key="Str_ForwardFastTooltip">10フレーム進める</s:String>
|
||||
<s:String x:Key="Str_FullScreenTooltip">ウィンドウ/フルスクリーン; F11</s:String>
|
||||
|
||||
<!-- 日志框下方附加信息 -->
|
||||
<s:String x:Key="Str_RealTimeFps">リアルタイムFPS:{0:F1}/{1:F1}</s:String>
|
||||
|
||||
<!-- 弹窗文本 -->
|
||||
<s:String x:Key="Str_OK">OK</s:String>
|
||||
<s:String x:Key="Str_Cancel">キャンセル</s:String>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
<s:String x:Key="Str_Tool">工具</s:String>
|
||||
<s:String x:Key="Str_Download">下载</s:String>
|
||||
<s:String x:Key="Str_Help">帮助</s:String>
|
||||
<s:String x:Key="Str_DownloadFFmpeg">前往下载 FFmpeg</s:String>
|
||||
<s:String x:Key="Str_Diagnostics">诊断信息</s:String>
|
||||
<s:String x:Key="Str_Abount">关于</s:String>
|
||||
<s:String x:Key="Str_Experiment">实验性功能</s:String>
|
||||
@@ -124,8 +123,6 @@
|
||||
<s:String x:Key="Str_MaxFpsTooltip">预览画面的最大帧率,设置为 0 时则无帧率限制</s:String>
|
||||
<s:String x:Key="Str_PlaySpeed">播放速度</s:String>
|
||||
<s:String x:Key="Str_WallpaperView">桌面投影</s:String>
|
||||
<s:String x:Key="Str_WallpaperMaxFps">桌面投影最大帧率</s:String>
|
||||
<s:String x:Key="Str_WallpaperMaxFpsTooltip">桌面投影的最大帧率,设置为 0 时则无帧率限制</s:String>
|
||||
<s:String x:Key="Str_RenderSelectedOnly">仅渲染选中</s:String>
|
||||
<s:String x:Key="Str_HitTestLevel">命中检测准确度等级</s:String>
|
||||
<s:String x:Key="Str_LogHitSlots">输出命中检测结果的插槽名称</s:String>
|
||||
@@ -143,9 +140,6 @@
|
||||
<s:String x:Key="Str_ForwardFastTooltip">快进 10 帧</s:String>
|
||||
<s:String x:Key="Str_FullScreenTooltip">窗口/全屏; F11</s:String>
|
||||
|
||||
<!-- 日志框下方附加信息 -->
|
||||
<s:String x:Key="Str_RealTimeFps">实时帧率:{0:F1}/{1:F1}</s:String>
|
||||
|
||||
<!-- 弹窗文本 -->
|
||||
<s:String x:Key="Str_OK">确认</s:String>
|
||||
<s:String x:Key="Str_Cancel">取消</s:String>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<utils:StringFormatMultiValueConverter x:Key="StrFmtCvter"/>
|
||||
<utils:BackgroundToForegroundConverter x:Key="Bg2FgCvter"/>
|
||||
|
||||
<Style x:Key="MyGridSplitterBaseStyle" TargetType="GridSplitter">
|
||||
<Style x:Key="MyGridSplitterBaseStyle" TargetType="{x:Type GridSplitter}">
|
||||
<Setter Property="Background" Value="{DynamicResource SecondaryBorderBrush}"/>
|
||||
<Setter Property="ShowsPreview" Value="False"/>
|
||||
<Style.Triggers>
|
||||
@@ -28,17 +28,17 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyToggleButtonBaseStyle" TargetType="ToggleButton" BasedOn="{StaticResource ToggleButtonSwitch}">
|
||||
<Style x:Key="MyToggleButtonBaseStyle" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource ToggleButtonSwitch}">
|
||||
<Setter Property="hc:VisualElement.HighlightBrush" Value="{DynamicResource DarkSuccessBrush}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyListBoxBaseStyle" TargetType="ListBox" BasedOn="{StaticResource ListBoxBaseStyle}">
|
||||
<Style x:Key="MyListBoxBaseStyle" TargetType="{x:Type ListBox}" BasedOn="{StaticResource ListBoxBaseStyle}">
|
||||
<Setter Property="SelectionMode" Value="Extended"/>
|
||||
<!--<Setter Property="VirtualizingPanel.IsVirtualizing" Value="False"/>-->
|
||||
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Visible"/>
|
||||
<Setter Property="ItemContainerStyle">
|
||||
<Setter.Value>
|
||||
<Style TargetType="ListBoxItem" BasedOn="{StaticResource ListBoxItemBaseStyle}">
|
||||
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource ListBoxItemBaseStyle}">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
@@ -47,26 +47,26 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyListViewBaseStyle" TargetType="ListView" BasedOn="{StaticResource ListViewBaseStyle}">
|
||||
<Style x:Key="MyListViewBaseStyle" TargetType="{x:Type ListView}" BasedOn="{StaticResource ListViewBaseStyle}">
|
||||
<Setter Property="SelectionMode" Value="Extended"/>
|
||||
<!--<Setter Property="VirtualizingPanel.IsVirtualizing" Value="False"/>-->
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="ItemContainerStyle" Value="{StaticResource ListViewItemBaseStyle.Small}"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyGroupBoxBaseStyle" TargetType="GroupBox" BasedOn="{StaticResource GroupBoxTab}">
|
||||
<Style x:Key="MyGroupBoxBaseStyle" TargetType="{x:Type GroupBox}" BasedOn="{StaticResource GroupBoxTab}">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="hc:TitleElement.Background" Value="Transparent"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyLogRichTextBoxStyle" TargetType="RichTextBox" BasedOn="{StaticResource RichTextBoxBaseStyle}">
|
||||
<Style x:Key="MyLogRichTextBoxStyle" TargetType="{x:Type RichTextBox}" BasedOn="{StaticResource RichTextBoxBaseStyle}">
|
||||
<Setter Property="IsReadOnly" Value="True"/>
|
||||
<Setter Property="FontFamily" Value="Consolas"/>
|
||||
<Setter Property="Block.LineHeight" Value="3"/>
|
||||
<Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyVerticalScrollViewerBaseStyle" TargetType="ScrollViewer" BasedOn="{StaticResource ScrollViewerNativeBaseStyle}">
|
||||
<Style x:Key="MyVerticalScrollViewerBaseStyle" TargetType="{x:Type ScrollViewer}" BasedOn="{StaticResource ScrollViewerNativeBaseStyle}">
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
|
||||
<Style.Triggers>
|
||||
@@ -99,24 +99,10 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MyLabelStyle" TargetType="Label" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Label">
|
||||
<Border CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
|
||||
<!-- 直接复制的原本 LabelDefault 的样式, 但是去除了 RecognizesAccessKey 防止不显示第一个下划线 -->
|
||||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="False" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="GridSplitter" BasedOn="{StaticResource MyGridSplitterBaseStyle}"/>
|
||||
<Style TargetType="ToggleButton" BasedOn="{StaticResource MyToggleButtonBaseStyle}"/>
|
||||
<Style TargetType="ListBox" BasedOn="{StaticResource MyListBoxBaseStyle}"/>
|
||||
<Style TargetType="ListView" BasedOn="{StaticResource MyListViewBaseStyle}"/>
|
||||
<Style TargetType="GroupBox" BasedOn="{StaticResource MyGroupBoxBaseStyle}"/>
|
||||
<Style TargetType="Label" BasedOn="{StaticResource MyLabelStyle}"/>
|
||||
<Style TargetType="{x:Type GridSplitter}" BasedOn="{StaticResource MyGridSplitterBaseStyle}"/>
|
||||
<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource MyToggleButtonBaseStyle}"/>
|
||||
<Style TargetType="{x:Type ListBox}" BasedOn="{StaticResource MyListBoxBaseStyle}"/>
|
||||
<Style TargetType="{x:Type ListView}" BasedOn="{StaticResource MyListViewBaseStyle}"/>
|
||||
<Style TargetType="{x:Type GroupBox}" BasedOn="{StaticResource MyGroupBoxBaseStyle}"/>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -6,12 +6,9 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.16.12</Version>
|
||||
<Version>0.16.11</Version>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
@@ -44,6 +41,5 @@
|
||||
<ProjectReference Include="..\NLog.Windows.Wpf\NLog.Windows.Wpf.csproj" />
|
||||
<ProjectReference Include="..\SFMLRenderer\SFMLRenderer.csproj" />
|
||||
<ProjectReference Include="..\Spine\Spine.csproj" />
|
||||
<ProjectReference Include="..\Win32Natives\Win32Natives.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace SpineViewer.Utils
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to read json file {0}, {1}", path, ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ namespace SpineViewer.Utils
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to save json file {0}, {1}", path, ex.Message);
|
||||
return false;
|
||||
}
|
||||
@@ -101,7 +101,7 @@ namespace SpineViewer.Utils
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to serialize json object {0}", ex.Message);
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace SpineViewer.ViewModels.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0}, {1}", output, ex.Message);
|
||||
}
|
||||
_vmMain.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
|
||||
@@ -169,7 +169,7 @@ namespace SpineViewer.ViewModels.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0}, {1}", output, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ namespace SpineViewer.ViewModels.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0}, {1}", output, ex.Message);
|
||||
}
|
||||
_vmMain.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
|
||||
@@ -206,7 +206,7 @@ namespace SpineViewer.ViewModels.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0}, {1}", output, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace SpineViewer.ViewModels.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0}, {1}", output, ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -121,7 +121,7 @@ namespace SpineViewer.ViewModels.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0}, {1}", output, ex.Message);
|
||||
}
|
||||
done++;
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace SpineViewer.ViewModels.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0}, {1}", output, ex.Message);
|
||||
}
|
||||
_vmMain.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
|
||||
@@ -133,7 +133,7 @@ namespace SpineViewer.ViewModels.Exporters
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to export {0}, {1}", output, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to generate preview: {0}, {1}", m.PreviewFilePath, ex.Message);
|
||||
}
|
||||
_logger.LogCurrentProcessMemoryUsage();
|
||||
@@ -221,7 +221,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to generate preview: {0}, {1}", m.PreviewFilePath, ex.Message);
|
||||
error++;
|
||||
}
|
||||
@@ -261,7 +261,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to delete preview: {0}, {1}", m.PreviewFilePath, ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -302,7 +302,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to delete preview: {0}, {1}", m.PreviewFilePath, ex.Message);
|
||||
error++;
|
||||
}
|
||||
@@ -340,7 +340,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to enumerate files in dir: {0}, {1}", _currentDirectory, ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -408,7 +408,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Warn("Failed to load preview image for {0}, {1}", FullPath, ex.Message);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using SFMLRenderer;
|
||||
using SpineViewer.Models;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.Utils;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
using System.Windows.Shell;
|
||||
|
||||
@@ -164,12 +163,6 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
JsonHelper.Serialize(Workspace, fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开 FFmpeg 下载页面
|
||||
/// </summary>
|
||||
public RelayCommand Cmd_DownloadFFmpeg => _cmd_DownloadFFmpeg ??= new(() => Process.Start(new ProcessStartInfo("https://ffmpeg.org/download.html") { UseShellExecute = true }));
|
||||
private RelayCommand? _cmd_DownloadFFmpeg;
|
||||
|
||||
/// <summary>
|
||||
/// 显示诊断信息对话框
|
||||
/// </summary>
|
||||
|
||||
@@ -5,6 +5,7 @@ using NLog;
|
||||
using Spine;
|
||||
using Spine.Implementations;
|
||||
using SpineViewer.Models;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
@@ -75,7 +76,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to load some prefereneces, {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -107,15 +108,12 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
DebugPoints = DebugPoints,
|
||||
DebugClippings = DebugClippings,
|
||||
|
||||
AppLanguage = AppLanguage,
|
||||
AppSkin = AppSkin,
|
||||
RenderSelectedOnly = RenderSelectedOnly,
|
||||
HitTestLevel = HitTestLevel,
|
||||
LogHitSlots = LogHitSlots,
|
||||
MaxFps = MaxFps,
|
||||
|
||||
AppLanguage = AppLanguage,
|
||||
AppSkin = AppSkin,
|
||||
WallpaperView = WallpaperView,
|
||||
WallpaperMaxFps = WallpaperMaxFps,
|
||||
CloseToTray = CloseToTray,
|
||||
AutoRun = AutoRun,
|
||||
AutoRunWorkspaceConfigPath = AutoRunWorkspaceConfigPath,
|
||||
@@ -142,15 +140,12 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
DebugPoints = value.DebugPoints;
|
||||
DebugClippings = value.DebugClippings;
|
||||
|
||||
AppLanguage = value.AppLanguage;
|
||||
AppSkin = value.AppSkin;
|
||||
RenderSelectedOnly = value.RenderSelectedOnly;
|
||||
HitTestLevel = value.HitTestLevel;
|
||||
LogHitSlots = value.LogHitSlots;
|
||||
MaxFps = value.MaxFps;
|
||||
|
||||
AppLanguage = value.AppLanguage;
|
||||
AppSkin = value.AppSkin;
|
||||
WallpaperView = value.WallpaperView;
|
||||
WallpaperMaxFps = value.WallpaperMaxFps;
|
||||
CloseToTray = value.CloseToTray;
|
||||
AutoRun = value.AutoRun;
|
||||
AutoRunWorkspaceConfigPath = value.AutoRunWorkspaceConfigPath;
|
||||
@@ -256,10 +251,26 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
|
||||
#endregion
|
||||
|
||||
#region 预览画面首选项
|
||||
#region 程序选项
|
||||
|
||||
public static ImmutableArray<AppLanguage> AppLanguageOptions { get; } = Enum.GetValues<AppLanguage>().ToImmutableArray();
|
||||
|
||||
public static ImmutableArray<AppSkin> AppSkinOptions { get; } = Enum.GetValues<AppSkin>().ToImmutableArray();
|
||||
|
||||
public static ImmutableArray<HitTestLevel> HitTestLevelOptions { get; } = Enum.GetValues<HitTestLevel>().ToImmutableArray();
|
||||
|
||||
public AppLanguage AppLanguage
|
||||
{
|
||||
get => ((App)App.Current).Language;
|
||||
set => SetProperty(((App)App.Current).Language, value, v => ((App)App.Current).Language = v);
|
||||
}
|
||||
|
||||
public AppSkin AppSkin
|
||||
{
|
||||
get => ((App)App.Current).Skin;
|
||||
set => SetProperty(((App)App.Current).Skin, value, v => ((App)App.Current).Skin = v);
|
||||
}
|
||||
|
||||
public bool RenderSelectedOnly
|
||||
{
|
||||
get => _vmMain.SFMLRendererViewModel.RenderSelectedOnly;
|
||||
@@ -278,44 +289,12 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
set => SetProperty(SpineExtension.LogHitSlots, value, v => SpineExtension.LogHitSlots = v);
|
||||
}
|
||||
|
||||
public uint MaxFps
|
||||
{
|
||||
get => _vmMain.SFMLRendererViewModel.MaxFps;
|
||||
set => SetProperty(_vmMain.SFMLRendererViewModel.MaxFps, value, v => _vmMain.SFMLRendererViewModel.MaxFps = v);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 程序选项
|
||||
|
||||
public static ImmutableArray<AppLanguage> AppLanguageOptions { get; } = Enum.GetValues<AppLanguage>().ToImmutableArray();
|
||||
|
||||
public static ImmutableArray<AppSkin> AppSkinOptions { get; } = Enum.GetValues<AppSkin>().ToImmutableArray();
|
||||
|
||||
public AppLanguage AppLanguage
|
||||
{
|
||||
get => ((App)App.Current).Language;
|
||||
set => SetProperty(((App)App.Current).Language, value, v => ((App)App.Current).Language = v);
|
||||
}
|
||||
|
||||
public AppSkin AppSkin
|
||||
{
|
||||
get => ((App)App.Current).Skin;
|
||||
set => SetProperty(((App)App.Current).Skin, value, v => ((App)App.Current).Skin = v);
|
||||
}
|
||||
|
||||
public bool WallpaperView
|
||||
{
|
||||
get => _vmMain.SFMLRendererViewModel.WallpaperView;
|
||||
set => SetProperty(_vmMain.SFMLRendererViewModel.WallpaperView, value, v => _vmMain.SFMLRendererViewModel.WallpaperView = v);
|
||||
}
|
||||
|
||||
public uint WallpaperMaxFps
|
||||
{
|
||||
get => _vmMain.SFMLRendererViewModel.WallpaperMaxFps;
|
||||
set => SetProperty(_vmMain.SFMLRendererViewModel.WallpaperMaxFps, value, v => _vmMain.SFMLRendererViewModel.WallpaperMaxFps = v);
|
||||
}
|
||||
|
||||
public bool CloseToTray
|
||||
{
|
||||
get => _vmMain.CloseToTray;
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
/// <summary>
|
||||
/// 坐标轴顶点缓冲区
|
||||
/// </summary>
|
||||
private readonly SFML.Graphics.VertexArray _axisVertices = new(SFML.Graphics.PrimitiveType.Lines, 4); // XXX: 暂时未使用 Dispose 释放
|
||||
private readonly SFML.Graphics.VertexArray _axisVertices = new(SFML.Graphics.PrimitiveType.Lines, 2); // XXX: 暂时未使用 Dispose 释放
|
||||
|
||||
/// <summary>
|
||||
/// 帧间隔计时器
|
||||
@@ -61,7 +61,6 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
/// 渲染任务
|
||||
/// </summary>
|
||||
private Task? _renderTask = null;
|
||||
private Task? _wallpaperRenderTask = null;
|
||||
private CancellationTokenSource? _cancelToken = null;
|
||||
|
||||
/// <summary>
|
||||
@@ -88,12 +87,6 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
_models = _vmMain.SpineObjects;
|
||||
_renderer = _vmMain.SFMLRenderer;
|
||||
_wallpaperRenderer = _vmMain.WallpaperRenderer;
|
||||
|
||||
// 画一个很长的坐标轴, 用 1e9 比较合适
|
||||
_axisVertices[0] = new(new(-1e9f, 0), _axisColor);
|
||||
_axisVertices[1] = new(new(1e9f, 0), _axisColor);
|
||||
_axisVertices[2] = new(new(0, -1e9f), _axisColor);
|
||||
_axisVertices[3] = new(new(0, 1e9f), _axisColor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -160,27 +153,9 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
public uint MaxFps
|
||||
{
|
||||
get => _renderer.MaxFps;
|
||||
set => SetProperty(_renderer.MaxFps, value, v => _renderer.MaxFps = value);
|
||||
set => SetProperty(_renderer.MaxFps, value, v => _renderer.MaxFps = _wallpaperRenderer.MaxFps = value);
|
||||
}
|
||||
|
||||
public uint WallpaperMaxFps
|
||||
{
|
||||
get => _wallpaperRenderer.MaxFps;
|
||||
set => SetProperty(_wallpaperRenderer.MaxFps, value, v => _wallpaperRenderer.MaxFps = value);
|
||||
}
|
||||
|
||||
public float RealTimeFps => _realTimeFps;
|
||||
private float _realTimeFps;
|
||||
|
||||
private float _accumFpsTime;
|
||||
private int _accumFpsCount;
|
||||
|
||||
public float WallpaperRealTimeFps => _wallpaperRealTimeFps;
|
||||
private float _wallpaperRealTimeFps;
|
||||
|
||||
private int _accumWallpaperFpsCount;
|
||||
private readonly object _accumWallpaperFpsCountLock = new();
|
||||
|
||||
public float Speed
|
||||
{
|
||||
get => _speed;
|
||||
@@ -213,7 +188,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
/// </summary>
|
||||
private SFML.Graphics.Color _axisColor = SFML.Graphics.Color.White;
|
||||
|
||||
public string? BackgroundImagePath
|
||||
public string BackgroundImagePath
|
||||
{
|
||||
get => _backgroundImagePath;
|
||||
set => SetProperty(_backgroundImagePath, value, v =>
|
||||
@@ -262,7 +237,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
});
|
||||
}
|
||||
private string? _backgroundImagePath;
|
||||
private string _backgroundImagePath;
|
||||
|
||||
public Stretch BackgroundImageMode
|
||||
{
|
||||
@@ -472,29 +447,26 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
{
|
||||
if (_renderTask is not null) return;
|
||||
_cancelToken = new();
|
||||
_renderTask = new(RenderTask, _cancelToken.Token, TaskCreationOptions.LongRunning);
|
||||
_wallpaperRenderTask = new(WallpaperRenderTask, _cancelToken.Token, TaskCreationOptions.LongRunning);
|
||||
_renderTask = new Task(RenderTask, _cancelToken.Token, TaskCreationOptions.LongRunning);
|
||||
_renderTask.Start();
|
||||
_wallpaperRenderTask.Start();
|
||||
IsUpdating = true;
|
||||
}
|
||||
|
||||
public void StopRender()
|
||||
{
|
||||
IsUpdating = false;
|
||||
if (_cancelToken is null || _renderTask is null || _wallpaperRenderTask is null) return;
|
||||
if (_renderTask is null || _cancelToken is null) return;
|
||||
_cancelToken.Cancel();
|
||||
_wallpaperRenderTask.Wait();
|
||||
_renderTask.Wait();
|
||||
_wallpaperRenderTask = null;
|
||||
_renderTask = null;
|
||||
_cancelToken = null;
|
||||
_renderTask = null;
|
||||
}
|
||||
|
||||
private void RenderTask()
|
||||
{
|
||||
try
|
||||
{
|
||||
_wallpaperRenderer.SetActive(true);
|
||||
_renderer.SetActive(true);
|
||||
|
||||
float delta;
|
||||
@@ -503,211 +475,111 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
delta = _clock.ElapsedTime.AsSeconds();
|
||||
_clock.Restart();
|
||||
|
||||
UpdateLogicFrame(delta);
|
||||
UpdateRenderFrame();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Fatal("Render task stopped, {0}", ex.Message);
|
||||
MessagePopupService.Error(ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
_renderer.SetActive(false);
|
||||
}
|
||||
}
|
||||
// 停止更新的时候只是时间不前进, 但是坐标变换还是要更新, 否则无法移动对象
|
||||
if (!_isUpdating) delta = 0;
|
||||
|
||||
private void UpdateLogicFrame(float delta)
|
||||
{
|
||||
// 计算实时帧率, 1 秒刷新一次
|
||||
_accumFpsTime += delta;
|
||||
if (_accumFpsTime > 1f)
|
||||
{
|
||||
_realTimeFps = _accumFpsCount / _accumFpsTime;
|
||||
_accumFpsCount = 0;
|
||||
|
||||
lock (_accumWallpaperFpsCountLock)
|
||||
{
|
||||
_wallpaperRealTimeFps = _accumWallpaperFpsCount / _accumFpsTime;
|
||||
_accumWallpaperFpsCount = 0;
|
||||
}
|
||||
|
||||
_accumFpsTime = 0f;
|
||||
OnPropertyChanged(nameof(RealTimeFps));
|
||||
OnPropertyChanged(nameof(WallpaperRealTimeFps));
|
||||
}
|
||||
|
||||
// 停止更新的时候只是时间不前进, 但是坐标变换还是要更新, 否则无法移动对象
|
||||
if (!_isUpdating) delta = 0;
|
||||
|
||||
// 加上要快进的量
|
||||
lock (_forwardDeltaLock)
|
||||
{
|
||||
delta += _forwardDelta;
|
||||
_forwardDelta = 0;
|
||||
}
|
||||
|
||||
// 更新模型对象时间
|
||||
lock (_models.Lock)
|
||||
{
|
||||
foreach (var sp in _models.Where(sp => sp.IsShown && (!_renderSelectedOnly || sp.IsSelected)).Reverse())
|
||||
{
|
||||
if (_cancelToken?.IsCancellationRequested ?? true) break; // 提前中止
|
||||
|
||||
sp.Update(0); // 避免物理效果出现问题
|
||||
sp.Update(delta * _speed);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新背景图位置和缩放
|
||||
lock (_bgLock)
|
||||
{
|
||||
if (_backgroundImageSprite is not null)
|
||||
{
|
||||
using var view = _renderer.GetView();
|
||||
var bg = _backgroundImageSprite;
|
||||
var viewSize = view.Size;
|
||||
var bgSize = bg.Texture.Size;
|
||||
var scaleX = Math.Abs(viewSize.X / bgSize.X);
|
||||
var scaleY = Math.Abs(viewSize.Y / bgSize.Y);
|
||||
var signX = Math.Sign(viewSize.X);
|
||||
var signY = Math.Sign(viewSize.Y);
|
||||
if (_backgroundImageMode == Stretch.None)
|
||||
// 加上要快进的量
|
||||
lock (_forwardDeltaLock)
|
||||
{
|
||||
scaleX = scaleY = 1f / _renderer.Zoom;
|
||||
}
|
||||
else if (_backgroundImageMode == Stretch.Uniform)
|
||||
{
|
||||
scaleX = scaleY = Math.Min(scaleX, scaleY);
|
||||
}
|
||||
else if (_backgroundImageMode == Stretch.UniformToFill)
|
||||
{
|
||||
scaleX = scaleY = Math.Max(scaleX, scaleY);
|
||||
}
|
||||
bg.Scale = new(signX * scaleX, signY * scaleY);
|
||||
bg.Position = view.Center;
|
||||
bg.Rotation = view.Rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRenderFrame()
|
||||
{
|
||||
if (!_vmMain.IsVisible)
|
||||
{
|
||||
// 必须休眠一会, 否则会空转影响整体渲染循环
|
||||
Thread.Sleep(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 清除背景
|
||||
_renderer.Clear(_backgroundColor);
|
||||
|
||||
// 渲染背景
|
||||
lock (_bgLock)
|
||||
{
|
||||
if (_backgroundImageSprite is not null)
|
||||
{
|
||||
_renderer.Draw(_backgroundImageSprite);
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染坐标轴
|
||||
if (_showAxis)
|
||||
{
|
||||
_renderer.Draw(_axisVertices);
|
||||
}
|
||||
|
||||
// 渲染 Spine
|
||||
lock (_models.Lock)
|
||||
{
|
||||
foreach (var sp in _models.Where(sp => sp.IsShown && (!_renderSelectedOnly || sp.IsSelected)).Reverse())
|
||||
{
|
||||
if (_cancelToken?.IsCancellationRequested ?? true) break; // 提前中止
|
||||
|
||||
// 为选中对象绘制一个半透明背景
|
||||
if (sp.IsSelected)
|
||||
{
|
||||
var rc = sp.GetCurrentBounds().ToFloatRect();
|
||||
_selectedBackgroundVertices[0] = new(new(rc.Left, rc.Top), _selectedBackgroundColor);
|
||||
_selectedBackgroundVertices[1] = new(new(rc.Left + rc.Width, rc.Top), _selectedBackgroundColor);
|
||||
_selectedBackgroundVertices[2] = new(new(rc.Left + rc.Width, rc.Top + rc.Height), _selectedBackgroundColor);
|
||||
_selectedBackgroundVertices[3] = new(new(rc.Left, rc.Top + rc.Height), _selectedBackgroundColor);
|
||||
_renderer.Draw(_selectedBackgroundVertices);
|
||||
delta += _forwardDelta;
|
||||
_forwardDelta = 0;
|
||||
}
|
||||
|
||||
// 仅在预览画面临时启用调试模式
|
||||
sp.EnableDebug = true;
|
||||
_renderer.Draw(sp);
|
||||
sp.EnableDebug = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 显示内容
|
||||
_renderer.Display();
|
||||
|
||||
// 帧数加一
|
||||
_accumFpsCount++;
|
||||
}
|
||||
|
||||
private void WallpaperRenderTask()
|
||||
{
|
||||
try
|
||||
{
|
||||
_wallpaperRenderer.SetActive(true);
|
||||
while (!_cancelToken?.IsCancellationRequested ?? false)
|
||||
{
|
||||
if (!_wallpaperView)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 同步视图
|
||||
using var view = _renderer.GetView();
|
||||
_wallpaperRenderer.SetView(view);
|
||||
|
||||
// 清除背景
|
||||
_wallpaperRenderer.Clear(_backgroundColor);
|
||||
if (_vmMain.IsVisible) _renderer.Clear(_backgroundColor);
|
||||
if (_wallpaperView) _wallpaperRenderer.Clear(_backgroundColor);
|
||||
|
||||
// 渲染背景
|
||||
lock (_bgLock)
|
||||
{
|
||||
if (_backgroundImageSprite is not null)
|
||||
{
|
||||
_wallpaperRenderer.Draw(_backgroundImageSprite);
|
||||
var bg = _backgroundImageSprite;
|
||||
var viewSize = view.Size;
|
||||
var bgSize = bg.Texture.Size;
|
||||
var scaleX = Math.Abs(viewSize.X / bgSize.X);
|
||||
var scaleY = Math.Abs(viewSize.Y / bgSize.Y);
|
||||
var signX = Math.Sign(viewSize.X);
|
||||
var signY = Math.Sign(viewSize.Y);
|
||||
if (_backgroundImageMode == Stretch.None)
|
||||
{
|
||||
scaleX = scaleY = 1f / _renderer.Zoom;
|
||||
}
|
||||
else if (_backgroundImageMode == Stretch.Uniform)
|
||||
{
|
||||
scaleX = scaleY = Math.Min(scaleX, scaleY);
|
||||
}
|
||||
else if (_backgroundImageMode == Stretch.UniformToFill)
|
||||
{
|
||||
scaleX = scaleY = Math.Max(scaleX, scaleY);
|
||||
}
|
||||
bg.Scale = new(signX * scaleX, signY * scaleY);
|
||||
bg.Position = view.Center;
|
||||
bg.Rotation = view.Rotation;
|
||||
|
||||
if (_vmMain.IsVisible) _renderer.Draw(bg);
|
||||
if (_wallpaperView) _wallpaperRenderer.Draw(bg);
|
||||
}
|
||||
}
|
||||
|
||||
if (_showAxis && _vmMain.IsVisible)
|
||||
{
|
||||
// 画一个很长的坐标轴, 用 1e9 比较合适
|
||||
_axisVertices[0] = new(new(-1e9f, 0), _axisColor);
|
||||
_axisVertices[1] = new(new(1e9f, 0), _axisColor);
|
||||
_renderer.Draw(_axisVertices);
|
||||
_axisVertices[0] = new(new(0, -1e9f), _axisColor);
|
||||
_axisVertices[1] = new(new(0, 1e9f), _axisColor);
|
||||
_renderer.Draw(_axisVertices);
|
||||
}
|
||||
|
||||
// 渲染 Spine
|
||||
lock (_models.Lock)
|
||||
{
|
||||
foreach (var sp in _models.Where(sp => sp.IsShown && (!_renderSelectedOnly || sp.IsSelected)).Reverse())
|
||||
{
|
||||
if (_cancelToken?.IsCancellationRequested ?? true)
|
||||
break; // 提前中止
|
||||
if (_cancelToken?.IsCancellationRequested ?? true) break; // 提前中止
|
||||
|
||||
_wallpaperRenderer.Draw(sp);
|
||||
sp.Update(0); // 避免物理效果出现问题
|
||||
sp.Update(delta * _speed);
|
||||
|
||||
if (_vmMain.IsVisible)
|
||||
{
|
||||
// 为选中对象绘制一个半透明背景
|
||||
if (sp.IsSelected)
|
||||
{
|
||||
var rc = sp.GetCurrentBounds().ToFloatRect();
|
||||
_selectedBackgroundVertices[0] = new(new(rc.Left, rc.Top), _selectedBackgroundColor);
|
||||
_selectedBackgroundVertices[1] = new(new(rc.Left + rc.Width, rc.Top), _selectedBackgroundColor);
|
||||
_selectedBackgroundVertices[2] = new(new(rc.Left + rc.Width, rc.Top + rc.Height), _selectedBackgroundColor);
|
||||
_selectedBackgroundVertices[3] = new(new(rc.Left, rc.Top + rc.Height), _selectedBackgroundColor);
|
||||
_renderer.Draw(_selectedBackgroundVertices);
|
||||
}
|
||||
|
||||
// 仅在预览画面临时启用调试模式
|
||||
sp.EnableDebug = true;
|
||||
_renderer.Draw(sp);
|
||||
sp.EnableDebug = false;
|
||||
}
|
||||
if (_wallpaperView) _wallpaperRenderer.Draw(sp);
|
||||
}
|
||||
}
|
||||
|
||||
// 显示渲染
|
||||
_wallpaperRenderer.Display();
|
||||
|
||||
// 帧数加一
|
||||
lock (_accumWallpaperFpsCountLock) _accumWallpaperFpsCount++;
|
||||
if (_vmMain.IsVisible) _renderer.Display();
|
||||
if (_wallpaperView) _wallpaperRenderer.Display();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Fatal("Wallpaper render task stopped, {0}", ex.Message);
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Fatal("Render task stopped, {0}", ex.Message);
|
||||
MessagePopupService.Error(ex.ToString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
_renderer.SetActive(false);
|
||||
_wallpaperRenderer.SetActive(false);
|
||||
}
|
||||
}
|
||||
@@ -726,6 +598,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
Rotation = Rotation,
|
||||
FlipX = FlipX,
|
||||
FlipY = FlipY,
|
||||
MaxFps = MaxFps,
|
||||
Speed = Speed,
|
||||
ShowAxis = ShowAxis,
|
||||
BackgroundColor = BackgroundColor,
|
||||
@@ -742,6 +615,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
Rotation = value.Rotation;
|
||||
FlipX = value.FlipX;
|
||||
FlipY = value.FlipY;
|
||||
MaxFps = value.MaxFps;
|
||||
Speed = value.Speed;
|
||||
ShowAxis = value.ShowAxis;
|
||||
BackgroundColor = value.BackgroundColor;
|
||||
|
||||
@@ -213,7 +213,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to load: {0}, {1}", skelPath, ex.Message);
|
||||
}
|
||||
return false;
|
||||
@@ -340,7 +340,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to reload spine {0}, {1}", sp.SkelPath, ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -401,7 +401,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
catch (Exception ex)
|
||||
{
|
||||
error++;
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to reload spine {0}, {1}", sp.SkelPath, ex.Message);
|
||||
}
|
||||
}
|
||||
@@ -718,7 +718,7 @@ namespace SpineViewer.ViewModels.MainWindow
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to load: {0}, {1}", cfg.SkelPath, ex.Message);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace SpineViewer.ViewModels
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Error("Failed to finish work: {0}, {1}", _title, ex.Message);
|
||||
WorkFinished?.Invoke(this, false);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<Grid Margin="30">
|
||||
<Grid.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
||||
</Style>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -14,7 +14,6 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Views
|
||||
{
|
||||
@@ -31,8 +30,9 @@ namespace SpineViewer.Views
|
||||
|
||||
private void AboutDialog_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
<Border>
|
||||
<Border.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Left"/>
|
||||
</Style>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -14,7 +14,6 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Views
|
||||
{
|
||||
@@ -31,8 +30,9 @@ namespace SpineViewer.Views
|
||||
|
||||
private void DiagnosticsDialog_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<Border>
|
||||
<Border.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
</Style>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Win32Natives;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.ViewModels.Exporters;
|
||||
@@ -16,7 +16,6 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using SpineViewer.Extensions;
|
||||
|
||||
namespace SpineViewer.Views.ExporterDialogs
|
||||
{
|
||||
@@ -33,8 +32,9 @@ namespace SpineViewer.Views.ExporterDialogs
|
||||
|
||||
private void CustomFFmpegExporterDialog_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
|
||||
private void ButtonOK_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<Border>
|
||||
<Border.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
</Style>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.ViewModels.Exporters;
|
||||
@@ -16,7 +16,6 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Views.ExporterDialogs
|
||||
{
|
||||
@@ -33,8 +32,9 @@ namespace SpineViewer.Views.ExporterDialogs
|
||||
|
||||
private void FFmpegVideoExporterDialog_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
|
||||
private void ButtonOK_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<Border>
|
||||
<Border.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
</Style>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.ViewModels.Exporters;
|
||||
@@ -16,7 +16,6 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Views.ExporterDialogs
|
||||
{
|
||||
@@ -33,8 +32,9 @@ namespace SpineViewer.Views.ExporterDialogs
|
||||
|
||||
private void FrameExporterDialog_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
|
||||
private void ButtonOK_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<Border>
|
||||
<Border.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
</Style>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.ViewModels.Exporters;
|
||||
@@ -16,7 +16,6 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Views.ExporterDialogs
|
||||
{
|
||||
@@ -33,8 +32,9 @@ namespace SpineViewer.Views.ExporterDialogs
|
||||
|
||||
private void FrameSequenceExporterDialog_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
|
||||
private void ButtonOK_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -62,8 +62,8 @@
|
||||
<!--<MenuItem Header="{DynamicResource Str_Tool}"/>-->
|
||||
<!--<MenuItem Header="{DynamicResource Str_Download}"/>-->
|
||||
<MenuItem Header="{DynamicResource Str_Help}">
|
||||
<MenuItem Header="{DynamicResource Str_DownloadFFmpeg}" Command="{Binding Cmd_DownloadFFmpeg}"/>
|
||||
<MenuItem Header="{DynamicResource Str_Diagnostics}" Command="{Binding Cmd_ShowDiagnosticsDialog}"/>
|
||||
<Separator/>
|
||||
<MenuItem Header="{DynamicResource Str_Abount}" Command="{Binding Cmd_ShowAboutDialog}"/>
|
||||
<MenuItem Header="{DynamicResource Str_Debug}" Click="DebugMenuItem_Click" Visibility="{Binding IsDebug, Mode=OneWay, Converter={StaticResource Boolean2VisibilityConverter}}"/>
|
||||
</MenuItem>
|
||||
@@ -239,7 +239,7 @@
|
||||
TabStripPlacement="Bottom"
|
||||
DataContext="{Binding SpineObjectTabViewModel}">
|
||||
<TabControl.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
</Style>
|
||||
@@ -695,7 +695,7 @@
|
||||
</Border>
|
||||
</TabItem.Header>
|
||||
<TabItem.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
</Style>
|
||||
@@ -793,6 +793,16 @@
|
||||
|
||||
<Separator Margin="0 5"/>
|
||||
|
||||
<!-- 最大帧率 -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="{DynamicResource Str_MaxFps}" ToolTip="{DynamicResource Str_MaxFpsTooltip}"/>
|
||||
<TextBox Grid.Column="1" Text="{Binding MaxFps}" ToolTip="{DynamicResource Str_MaxFpsTooltip}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- 播放速度 -->
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -902,16 +912,14 @@
|
||||
</Grid>
|
||||
|
||||
<StatusBar DockPanel.Dock="Bottom">
|
||||
<StatusBarItem>
|
||||
<TextBlock Foreground="{DynamicResource PrimaryTextBrush}">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{StaticResource StrFmtCvter}" ConverterParameter="Str_ListViewStatusBar">
|
||||
<Binding Path="Items.Count" ElementName="_spineFilesListBox"/>
|
||||
<Binding Path="SelectedItems.Count" ElementName="_spineFilesListBox"/>
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</StatusBarItem>
|
||||
<TextBlock Foreground="{DynamicResource PrimaryTextBrush}">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{StaticResource StrFmtCvter}" ConverterParameter="Str_ListViewStatusBar">
|
||||
<Binding Path="Items.Count" ElementName="_spineFilesListBox"/>
|
||||
<Binding Path="SelectedItems.Count" ElementName="_spineFilesListBox"/>
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</StatusBar>
|
||||
|
||||
<ListBox x:Name="_spineFilesListBox"
|
||||
@@ -947,7 +955,7 @@
|
||||
|
||||
<Grid Grid.Row="2" DataContext="{Binding SelectedItem}">
|
||||
<Grid.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
</Style>
|
||||
@@ -1044,23 +1052,7 @@
|
||||
|
||||
<!-- 日志框容器 -->
|
||||
<Border Grid.Row="2" Name="_loggerBoxContainer">
|
||||
<Border x:Name="_loggerBoxPanel" DataContext="{Binding SFMLRendererViewModel}">
|
||||
<DockPanel>
|
||||
<StatusBar DockPanel.Dock="Bottom">
|
||||
<StatusBarItem>
|
||||
<TextBlock Foreground="{DynamicResource PrimaryTextBrush}">
|
||||
<TextBlock.Text>
|
||||
<MultiBinding Converter="{StaticResource StrFmtCvter}" ConverterParameter="Str_RealTimeFps">
|
||||
<Binding Path="RealTimeFps"/>
|
||||
<Binding Path="WallpaperRealTimeFps"/>
|
||||
</MultiBinding>
|
||||
</TextBlock.Text>
|
||||
</TextBlock>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
<RichTextBox x:Name="_loggerRichTextBox" Grid.Row="2" Style="{StaticResource MyLogRichTextBoxStyle}"/>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
<RichTextBox x:Name="_loggerRichTextBox" Grid.Row="2" Style="{StaticResource MyLogRichTextBoxStyle}"/>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using NLog;
|
||||
using SFMLRenderer;
|
||||
using Spine;
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Models;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.Utils;
|
||||
@@ -24,7 +24,6 @@ using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Threading;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Views;
|
||||
|
||||
@@ -48,7 +47,7 @@ public partial class MainWindow : Window
|
||||
|
||||
private readonly List<IDisposable> _userStateWatchers = [];
|
||||
private DispatcherTimer _saveUserStateTimer;
|
||||
private readonly TimeSpan _saveTimerDelay = TimeSpan.FromSeconds(1);
|
||||
private readonly TimeSpan _saveTimerDelay = TimeSpan.FromSeconds(3);
|
||||
|
||||
public bool RootGridCol0Folded
|
||||
{
|
||||
@@ -99,13 +98,13 @@ public partial class MainWindow : Window
|
||||
|
||||
// Initialize Wallpaper RenderWindow
|
||||
_wallpaperRenderWindow = new(new(1, 1), "SpineViewerWallpaper", SFML.Window.Styles.None);
|
||||
_wallpaperRenderWindow.MaxFps = 30;
|
||||
|
||||
_wallpaperRenderWindow.SetVisible(false);
|
||||
var handle = _wallpaperRenderWindow.SystemHandle;
|
||||
var style = User32.GetWindowLong(handle, User32.GWL_STYLE) | User32.WS_POPUP;
|
||||
var exStyle = User32.GetWindowLong(handle, User32.GWL_EXSTYLE) | User32.WS_EX_TOOLWINDOW;
|
||||
var exStyle = User32.GetWindowLong(handle, User32.GWL_EXSTYLE) | User32.WS_EX_LAYERED | User32.WS_EX_TOOLWINDOW;
|
||||
User32.SetWindowLong(handle, User32.GWL_STYLE, style);
|
||||
User32.SetWindowLong(handle, User32.GWL_EXSTYLE, exStyle);
|
||||
User32.SetLayeredWindowAttributes(handle, 0, byte.MaxValue, User32.LWA_ALPHA);
|
||||
|
||||
DataContext = _vm = new(_renderPanel, _wallpaperRenderWindow);
|
||||
|
||||
@@ -154,8 +153,9 @@ public partial class MainWindow : Window
|
||||
|
||||
private void MainWindow_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
|
||||
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
|
||||
@@ -274,6 +274,7 @@ public partial class MainWindow : Window
|
||||
_vm.ExplorerListViewModel.CurrentDirectory = m.ExploringDirectory;
|
||||
|
||||
_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;
|
||||
@@ -309,6 +310,7 @@ public partial class MainWindow : Window
|
||||
|
||||
ResolutionX = _vm.SFMLRendererViewModel.ResolutionX,
|
||||
ResolutionY = _vm.SFMLRendererViewModel.ResolutionY,
|
||||
MaxFps = _vm.SFMLRendererViewModel.MaxFps,
|
||||
Speed = _vm.SFMLRendererViewModel.Speed,
|
||||
ShowAxis = _vm.SFMLRendererViewModel.ShowAxis,
|
||||
BackgroundColor = _vm.SFMLRendererViewModel.BackgroundColor,
|
||||
@@ -398,6 +400,7 @@ public partial class MainWindow : Window
|
||||
{
|
||||
case nameof(SFMLRendererViewModel.ResolutionX):
|
||||
case nameof(SFMLRendererViewModel.ResolutionY):
|
||||
case nameof(SFMLRendererViewModel.MaxFps):
|
||||
case nameof(SFMLRendererViewModel.Speed):
|
||||
case nameof(SFMLRendererViewModel.ShowAxis):
|
||||
case nameof(SFMLRendererViewModel.BackgroundColor):
|
||||
@@ -437,7 +440,6 @@ public partial class MainWindow : Window
|
||||
|
||||
private void SFMLRendererViewModel_PropertyChanged(object? sender, PropertyChangedEventArgs e)
|
||||
{
|
||||
// XXX: 资源管理器重启后窗口会有问题无法重新显示, 需要重启应用, 否则要重新创建窗口
|
||||
if (e.PropertyName == nameof(SFMLRendererViewModel.WallpaperView))
|
||||
{
|
||||
var wnd = _wallpaperRenderWindow;
|
||||
@@ -449,25 +451,17 @@ public partial class MainWindow : Window
|
||||
_logger.Error("Failed to enable wallpaper view, WorkerW not found");
|
||||
return;
|
||||
}
|
||||
|
||||
User32.GetPrimaryScreenResolution(out var sw, out var sh);
|
||||
_vm.SFMLRendererViewModel.SetResolution(sw, sh);
|
||||
|
||||
var handle = wnd.SystemHandle;
|
||||
|
||||
// 每次都进行设置, 确保会成为顶层子窗口
|
||||
var lastParent = User32.SetParent(handle, workerw);
|
||||
Debug.WriteLine($"0x{lastParent:x8} = SetParent(0x{handle:x8}, 0x{workerw:x8})");
|
||||
User32.GetPrimaryScreenResolution(out var sw, out var sh);
|
||||
|
||||
User32.SetParent(handle, workerw);
|
||||
User32.SetLayeredWindowAttributes(handle, 0, byte.MaxValue, User32.LWA_ALPHA);
|
||||
|
||||
// XXX: 每次新设置成桌面子窗口之后, 要确保窗口 Size 发生一次变化来触发 SFML 内部的渲染视图更新
|
||||
var ssize = new SFML.System.Vector2u(sw, sh);
|
||||
if (lastParent != workerw && ssize == wnd.Size)
|
||||
{
|
||||
wnd.Size = new(sw + 1, sh);
|
||||
}
|
||||
_vm.SFMLRendererViewModel.SetResolution(sw, sh);
|
||||
wnd.Position = new(0, 0);
|
||||
wnd.Size = ssize;
|
||||
wnd.Size = new(sw + 1, sh);
|
||||
wnd.Size = new(sw, sh);
|
||||
wnd.SetVisible(true);
|
||||
}
|
||||
else
|
||||
@@ -700,7 +694,7 @@ public partial class MainWindow : Window
|
||||
_renderPanelButtonsPopupContainer.Child = _renderPanelButtonsPanel;
|
||||
|
||||
_loggerBoxContainer.Child = null;
|
||||
_loggerBoxPopupContainer.Child = _loggerBoxPanel;
|
||||
_loggerBoxPopupContainer.Child = _loggerRichTextBox;
|
||||
}
|
||||
|
||||
private void SwitchToNormalLayout()
|
||||
@@ -710,7 +704,7 @@ public partial class MainWindow : Window
|
||||
HandyControl.Controls.IconElement.SetGeometry(_fullScreenButton, AppResource.Geo_ArrowsMaximize);
|
||||
|
||||
_loggerBoxPopupContainer.Child = null;
|
||||
_loggerBoxContainer.Child = _loggerBoxPanel;
|
||||
_loggerBoxContainer.Child = _loggerRichTextBox;
|
||||
|
||||
_renderPanelButtonsPopupContainer.Child = null;
|
||||
_renderPanelButtonsContainer.Child = _renderPanelButtonsPanel;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<Border>
|
||||
<Border.Resources>
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource MyLabelStyle}">
|
||||
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource LabelDefault}">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Right"/>
|
||||
</Style>
|
||||
@@ -195,8 +195,30 @@
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="{DynamicResource Str_RendererPreference}">
|
||||
<GroupBox Header="{DynamicResource Str_AppPreference}">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="{DynamicResource Str_Language}"/>
|
||||
<ComboBox Grid.Column="1"
|
||||
SelectedItem="{Binding AppLanguage}"
|
||||
ItemsSource="{x:Static vm:PreferenceViewModel.AppLanguageOptions}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="{DynamicResource Str_Skin}"/>
|
||||
<ComboBox Grid.Column="1"
|
||||
SelectedItem="{Binding AppSkin}"
|
||||
ItemsSource="{x:Static vm:PreferenceViewModel.AppSkinOptions}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
@@ -226,41 +248,6 @@
|
||||
<ToggleButton Grid.Column="1" IsChecked="{Binding LogHitSlots}" ToolTip="{DynamicResource Str_LogHitSlotsTooltip}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="{DynamicResource Str_MaxFps}" ToolTip="{DynamicResource Str_MaxFpsTooltip}"/>
|
||||
<TextBox Grid.Column="1" Text="{Binding MaxFps}" ToolTip="{DynamicResource Str_MaxFpsTooltip}"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="{DynamicResource Str_AppPreference}">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="{DynamicResource Str_Language}"/>
|
||||
<ComboBox Grid.Column="1"
|
||||
SelectedItem="{Binding AppLanguage}"
|
||||
ItemsSource="{x:Static vm:PreferenceViewModel.AppLanguageOptions}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="{DynamicResource Str_Skin}"/>
|
||||
<ComboBox Grid.Column="1"
|
||||
SelectedItem="{Binding AppSkin}"
|
||||
ItemsSource="{x:Static vm:PreferenceViewModel.AppSkinOptions}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
@@ -270,15 +257,6 @@
|
||||
<ToggleButton Grid.Column="1" IsChecked="{Binding WallpaperView}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Content="{DynamicResource Str_WallpaperMaxFps}" ToolTip="{DynamicResource Str_WallpaperMaxFpsTooltip}"/>
|
||||
<TextBox Grid.Column="1" Text="{Binding WallpaperMaxFps}" ToolTip="{DynamicResource Str_WallpaperMaxFpsTooltip}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol"/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.Services;
|
||||
using SpineViewer.ViewModels.Exporters;
|
||||
@@ -16,7 +16,6 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Views
|
||||
{
|
||||
@@ -33,8 +32,9 @@ namespace SpineViewer.Views
|
||||
|
||||
private void PreferenceDialog_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
|
||||
private void ButtonOK_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Resources;
|
||||
using SpineViewer.ViewModels;
|
||||
using System;
|
||||
@@ -16,7 +16,6 @@ using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Win32Natives;
|
||||
|
||||
namespace SpineViewer.Views
|
||||
{
|
||||
@@ -34,19 +33,29 @@ namespace SpineViewer.Views
|
||||
|
||||
private void ProgressDialog_SourceInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
this.SetWindowTextColor(AppResource.Color_PrimaryText);
|
||||
this.SetWindowCaptionColor(AppResource.Color_Region);
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
Dwmapi.SetWindowTextColor(hwnd, AppResource.Color_PrimaryText);
|
||||
Dwmapi.SetWindowCaptionColor(hwnd, AppResource.Color_Region);
|
||||
}
|
||||
|
||||
private void ProgressWindow_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var hwnd = new WindowInteropHelper(this).Handle;
|
||||
int currentStyle = User32.GetWindowLong(hwnd, User32.GWL_STYLE);
|
||||
User32.SetWindowLong(hwnd, User32.GWL_STYLE, currentStyle & ~User32.WS_SYSMENU);
|
||||
int currentStyle = GetWindowLong(hwnd, GWL_STYLE);
|
||||
SetWindowLong(hwnd, GWL_STYLE, currentStyle & ~WS_SYSMENU);
|
||||
|
||||
var vm = (ProgressDialogViewModel)DataContext;
|
||||
vm.WorkFinished += (s, e) => Dispatcher.Invoke(() => { DialogResult = e; });
|
||||
vm.Start();
|
||||
}
|
||||
|
||||
private const int GWL_STYLE = -16;
|
||||
private const int WS_SYSMENU = 0x80000;
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace SpineViewerCLI
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Debug(ex.ToString());
|
||||
_logger.Trace(ex.ToString());
|
||||
_logger.Fatal("Failed to execute, {0}", ex.Message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -6,12 +6,9 @@
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.16.12</Version>
|
||||
<Version>0.16.11</Version>
|
||||
<OutputType>Exe</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<OutputPath>$(BaseOutputPath)\$(Configuration)\$(PlatformTarget)</OutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>0.16.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user