Compare commits
350 Commits
v0.10.8
...
release/wf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acf48cd74d | ||
|
|
2fecf4223a | ||
|
|
2953ec44fb | ||
|
|
77399b4524 | ||
|
|
b34639c383 | ||
|
|
c0e2bb81e5 | ||
|
|
55ebcc1857 | ||
|
|
e3a201af89 | ||
|
|
292ede8461 | ||
|
|
112a9a1bf2 | ||
|
|
63ed8d7ca4 | ||
|
|
d1e33c25bc | ||
|
|
ce7c6f3802 | ||
|
|
0a30af0ad2 | ||
|
|
0b478cab18 | ||
|
|
b14849a0b1 | ||
|
|
b7f5f24e6f | ||
|
|
150331d2e4 | ||
|
|
dcec8797b0 | ||
|
|
4d1aec9ed8 | ||
|
|
0cb325820b | ||
|
|
2a862b28be | ||
|
|
c2935f49e9 | ||
|
|
22043f8f38 | ||
|
|
3020a818f0 | ||
|
|
30177e8d7f | ||
|
|
3ad49838be | ||
|
|
3e480abd44 | ||
|
|
49f6b28aef | ||
|
|
b81d13b582 | ||
|
|
04eb3cb640 | ||
|
|
0ac75a088a | ||
|
|
cd652a72a1 | ||
|
|
828ff30dbf | ||
|
|
f452fe8a71 | ||
|
|
15e29a3b8a | ||
|
|
5c6e98f5e1 | ||
|
|
ef06073119 | ||
|
|
bca8b0ad85 | ||
|
|
4983b1fa88 | ||
|
|
f6b6d9f0e7 | ||
|
|
12a168df92 | ||
|
|
e06d2012d6 | ||
|
|
faed2448eb | ||
|
|
a80aed54a0 | ||
|
|
3f9c4dfe99 | ||
|
|
3c91f335fc | ||
|
|
1ea4586360 | ||
|
|
45e08b5b60 | ||
|
|
43ce5a5288 | ||
|
|
887315ceda | ||
|
|
30b5c8dd74 | ||
|
|
ef7ef76a59 | ||
|
|
a9834bcc13 | ||
|
|
ec2752464d | ||
|
|
7b6a9b2a0f | ||
|
|
8eda4f0849 | ||
|
|
cde25214ae | ||
|
|
9f1f66776c | ||
|
|
c93b78528d | ||
|
|
e567e61383 | ||
|
|
7c3184d88a | ||
|
|
e6f38657a3 | ||
|
|
ebcd61a9a2 | ||
|
|
179fbfe84f | ||
|
|
79441abff3 | ||
|
|
c3db8cd4ea | ||
|
|
27c58ffd87 | ||
|
|
244249db2b | ||
|
|
33b937da87 | ||
|
|
058834e8a6 | ||
|
|
b134af3727 | ||
|
|
6d2eafb4f1 | ||
|
|
9f618804df | ||
|
|
61a3a62b65 | ||
|
|
ced25dec87 | ||
|
|
60d5f3361a | ||
|
|
c8ee4cf0c9 | ||
|
|
177434e503 | ||
|
|
58b45cde31 | ||
|
|
ff87030894 | ||
|
|
7635adf637 | ||
|
|
ca7a40044c | ||
|
|
ce5be30f1d | ||
|
|
1cb8f077f5 | ||
|
|
61794cf784 | ||
|
|
045b191e4d | ||
|
|
6116f6a4be | ||
|
|
ca7e94a306 | ||
|
|
165be38cfe | ||
|
|
f1fb5fe5e1 | ||
|
|
17554d3a8e | ||
|
|
054ac3939b | ||
|
|
9566c0a6f5 | ||
|
|
b8509ccb69 | ||
|
|
1e043e4faa | ||
|
|
5b1c177f58 | ||
|
|
794de783db | ||
|
|
7f6aa26986 | ||
|
|
fcd809fda5 | ||
|
|
71ff8007fb | ||
|
|
a8261f4f58 | ||
|
|
bb6a6f3664 | ||
|
|
9c6af07d32 | ||
|
|
afc011adbb | ||
|
|
da42c14d35 | ||
|
|
a7438e2026 | ||
|
|
47e5314bb3 | ||
|
|
1978c1da11 | ||
|
|
914c9d0ea3 | ||
|
|
7134aebb7f | ||
|
|
abb32e9ed2 | ||
|
|
2c77e385c5 | ||
|
|
ba0f5ac124 | ||
|
|
c4f17e3f06 | ||
|
|
b802ec252a | ||
|
|
68779caab0 | ||
|
|
5d819114d0 | ||
|
|
46b3937236 | ||
|
|
6803b8cf4a | ||
|
|
bd9c5a176b | ||
|
|
76c1d96c87 | ||
|
|
304af805cb | ||
|
|
027d3af619 | ||
|
|
c612c01ac7 | ||
|
|
cd7855a877 | ||
|
|
cdd81e0bfb | ||
|
|
750a8b8aff | ||
|
|
cd86155878 | ||
|
|
16739c39d6 | ||
|
|
c7971a9829 | ||
|
|
44c4fc4b21 | ||
|
|
6f1c8e3320 | ||
|
|
8f818416ba | ||
|
|
de6858ca48 | ||
|
|
3fd3d2a378 | ||
|
|
706c9125e6 | ||
|
|
5f026b000c | ||
|
|
0b0d036f08 | ||
|
|
6b9017d535 | ||
|
|
5eb47e33ac | ||
|
|
4d31335da0 | ||
|
|
0b5e76a448 | ||
|
|
775268c01a | ||
|
|
b0b1c85047 | ||
|
|
5f08fc6695 | ||
|
|
2de3bdf12b | ||
|
|
3a424c7dc1 | ||
|
|
c3e2b37072 | ||
|
|
65bd11a346 | ||
|
|
e6e7fc539f | ||
|
|
6522d415b7 | ||
|
|
378c66a333 | ||
|
|
07204417a5 | ||
|
|
c9c909cdf9 | ||
|
|
a9f59a4d2f | ||
|
|
1d2513cef5 | ||
|
|
febb797ae2 | ||
|
|
68d279a7c3 | ||
|
|
d2d8b7955c | ||
|
|
2a55fd9c36 | ||
|
|
695d3c0735 | ||
|
|
ce95db469b | ||
|
|
5d187cf80f | ||
|
|
e704ebc224 | ||
|
|
ee36f8981c | ||
|
|
09dd220abf | ||
|
|
15bc2dc3b8 | ||
|
|
1deb74eca9 | ||
|
|
de76ce64ab | ||
|
|
94b4ba33e6 | ||
|
|
7ce8a115f4 | ||
|
|
c036a4bb45 | ||
|
|
aa62f30b05 | ||
|
|
3d967c9812 | ||
|
|
e87e9efb99 | ||
|
|
8c1f6fb4a6 | ||
|
|
df82ed8a00 | ||
|
|
d01e3920ba | ||
|
|
777cd5ea3f | ||
|
|
3b73aea5c0 | ||
|
|
168f7a8173 | ||
|
|
04437e2de2 | ||
|
|
2ec83b2e87 | ||
|
|
90bfaa7b56 | ||
|
|
2ae175abd0 | ||
|
|
e2a84d8f88 | ||
|
|
b6f9cd0c7c | ||
|
|
61b7b90722 | ||
|
|
093c159753 | ||
|
|
32d36c0757 | ||
|
|
94dabebf2b | ||
|
|
8e875d4f7e | ||
|
|
86c383f2cf | ||
|
|
b404d8e79a | ||
|
|
d32b480ef2 | ||
|
|
3654825f27 | ||
|
|
d7231e8a09 | ||
|
|
98161aaf2e | ||
|
|
7a942b16bc | ||
|
|
067719c69b | ||
|
|
f3fce53b91 | ||
|
|
e35903f436 | ||
|
|
64cfe5fdd7 | ||
|
|
dbe586cff8 | ||
|
|
3104733db0 | ||
|
|
9d4bdd1028 | ||
|
|
f8030b1645 | ||
|
|
0a999ceb41 | ||
|
|
64bd9907cb | ||
|
|
580eaf990d | ||
|
|
5ab232a961 | ||
|
|
e596cd7ea4 | ||
|
|
05c47a4daa | ||
|
|
5a8783b5f4 | ||
|
|
08bc171a72 | ||
|
|
7372f5fe08 | ||
|
|
6f032bdd05 | ||
|
|
153d3603d2 | ||
|
|
95261e6907 | ||
|
|
17b344376d | ||
|
|
0ed4e44878 | ||
|
|
b42c1832f0 | ||
|
|
058534ba67 | ||
|
|
204dcd6498 | ||
|
|
2c846c0db9 | ||
|
|
2faeb044e0 | ||
|
|
09c8e4f779 | ||
|
|
6994fa6be8 | ||
|
|
cc7beb7670 | ||
|
|
510653732d | ||
|
|
93e8178d67 | ||
|
|
cebc4864cc | ||
|
|
6ad0449376 | ||
|
|
c33c977326 | ||
|
|
f0299d365a | ||
|
|
6ecdca73f5 | ||
|
|
af6a709b2c | ||
|
|
d5c27450ef | ||
|
|
d10269fb07 | ||
|
|
53d987476e | ||
|
|
8b7866d37f | ||
|
|
bb529729b6 | ||
|
|
b7735d9ba8 | ||
|
|
ce744e2b84 | ||
|
|
631c92da3f | ||
|
|
b7063804e9 | ||
|
|
75d47c8419 | ||
|
|
114fb05e80 | ||
|
|
1fec65b37d | ||
|
|
9498e8f334 | ||
|
|
83b8411929 | ||
|
|
e9accd13b3 | ||
|
|
9e27a19258 | ||
|
|
252f3a5bea | ||
|
|
e0626bb126 | ||
|
|
7ff62c7f40 | ||
|
|
4b07e02acb | ||
|
|
4654d1d9c2 | ||
|
|
ce1f75e8a5 | ||
|
|
4d9aebc758 | ||
|
|
e814368ef3 | ||
|
|
bbbb02500f | ||
|
|
404f255f14 | ||
|
|
7a15e0d38a | ||
|
|
bfe669bdd9 | ||
|
|
c0553042fd | ||
|
|
af8b02654b | ||
|
|
4779ec91d0 | ||
|
|
14d7f4af0e | ||
|
|
f9888b23dd | ||
|
|
411cdbb00f | ||
|
|
d859f07469 | ||
|
|
c111819093 | ||
|
|
aa8321d13c | ||
|
|
5e3bd972e5 | ||
|
|
ad39a04fff | ||
|
|
9a97e84296 | ||
|
|
1b7b0dcb13 | ||
|
|
d365a5060b | ||
|
|
b69589394a | ||
|
|
00f5791766 | ||
|
|
38cab2eda7 | ||
|
|
0db4d6e4e0 | ||
|
|
549712962f | ||
|
|
34b7002faf | ||
|
|
0e6f47b23c | ||
|
|
a372a89b5e | ||
|
|
239847aee7 | ||
|
|
813249c6a7 | ||
|
|
293ab28bce | ||
|
|
98e73cdec5 | ||
|
|
6d34bb9d25 | ||
|
|
479a5e4da9 | ||
|
|
4829454877 | ||
|
|
28664f6387 | ||
|
|
1a08a23a9c | ||
|
|
16f344ff1b | ||
|
|
693ce0e2e8 | ||
|
|
e6f533ea65 | ||
|
|
fcc21d63b0 | ||
|
|
afc0ffcb67 | ||
|
|
9ffb9840e1 | ||
|
|
4766ccf1b6 | ||
|
|
16b75c80a3 | ||
|
|
880f063046 | ||
|
|
723c11b886 | ||
|
|
5e074b1cf7 | ||
|
|
71d2fee36e | ||
|
|
7dc701464f | ||
|
|
fd876ef90f | ||
|
|
0597852178 | ||
|
|
81b1333091 | ||
|
|
7baebd79a6 | ||
|
|
951d0e30ae | ||
|
|
711e172769 | ||
|
|
faa60f0ea1 | ||
|
|
99d81c4329 | ||
|
|
17904326f3 | ||
|
|
5ee74f39d8 | ||
|
|
72f898ed60 | ||
|
|
157eab5bac | ||
|
|
e1b0d0a2ad | ||
|
|
2c050ba031 | ||
|
|
41518b16b4 | ||
|
|
72a16dc95f | ||
|
|
3404c64f55 | ||
|
|
b9015422f8 | ||
|
|
a7441b968d | ||
|
|
2d44be31f7 | ||
|
|
c2cf25bb2b | ||
|
|
7c4c53dcb0 | ||
|
|
aceb3b17c8 | ||
|
|
adfcfdb1de | ||
|
|
da329723bc | ||
|
|
63eb53fa06 | ||
|
|
d32c824515 | ||
|
|
e9ee8c481c | ||
|
|
6d78e52605 | ||
|
|
90136a5562 | ||
|
|
1592767c8c | ||
|
|
afa6ce2113 | ||
|
|
50e6e414ee | ||
|
|
ba9b8edcdc | ||
|
|
d7a927475c | ||
|
|
afe210343f | ||
|
|
4e293daf62 | ||
|
|
f9d7fdc516 | ||
|
|
6a04f3955c | ||
|
|
dce3b1780c |
70
.github/workflows/dotnet-desktop.yml
vendored
70
.github/workflows/dotnet-desktop.yml
vendored
@@ -1,46 +1,80 @@
|
||||
name: Build & Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
pull_request:
|
||||
branches:
|
||||
- release/wf
|
||||
types:
|
||||
- closed
|
||||
|
||||
jobs:
|
||||
build-release:
|
||||
if: ${{ github.event.pull_request.merged == true }}
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
PROJECT_NAME: SpineViewer
|
||||
VERSION: ${{ github.ref_name }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
with:
|
||||
fetch-tags: true
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: "8.0.x"
|
||||
|
||||
- name: Extract version from csproj
|
||||
shell: pwsh
|
||||
run: |
|
||||
[xml]$proj = Get-Content "$env:PROJECT_NAME\$env:PROJECT_NAME.csproj"
|
||||
$VERSION_NUM = $proj.Project.PropertyGroup.Version
|
||||
$VERSION_TAG = "v$VERSION_NUM"
|
||||
"VERSION=$VERSION_TAG" >> $env:GITHUB_ENV
|
||||
|
||||
- name: Check Version Tag
|
||||
shell: pwsh
|
||||
run: |
|
||||
if (-not $env:VERSION) {
|
||||
Write-Error "Version tag not found in csproj file."
|
||||
exit 1
|
||||
}
|
||||
Write-Host "Version tag found: $env:VERSION"
|
||||
|
||||
- name: Tag merge commit
|
||||
shell: pwsh
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git tag $env:VERSION
|
||||
git push --tags
|
||||
|
||||
- name: Publish FrameworkDependent version
|
||||
shell: pwsh
|
||||
run: |
|
||||
dotnet publish ${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj -c Release -r win-x64 --sc false -p:PublishSingleFile=true -o publish/${{ env.PROJECT_NAME }}-${{ env.VERSION }}
|
||||
|
||||
dotnet publish "$env:PROJECT_NAME\$env:PROJECT_NAME.csproj" -c Release -r win-x64 --sc false -o "publish\$env:PROJECT_NAME-$env:VERSION"
|
||||
|
||||
- name: Publish SelfContained version
|
||||
shell: pwsh
|
||||
run: |
|
||||
dotnet publish ${{ env.PROJECT_NAME }}/${{ env.PROJECT_NAME }}.csproj -c Release -r win-x64 --sc true -p:PublishSingleFile=true -o publish/${{ env.PROJECT_NAME }}-${{ env.VERSION }}-SelfContained
|
||||
|
||||
dotnet publish "$env:PROJECT_NAME\$env:PROJECT_NAME.csproj" -c Release -r win-x64 --sc true -o "publish\$env:PROJECT_NAME-$env:VERSION-SelfContained"
|
||||
|
||||
- name: Create release directory
|
||||
run: mkdir release
|
||||
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Path release -Force | Out-Null
|
||||
|
||||
- name: Compress FrameworkDependent version
|
||||
shell: pwsh
|
||||
run: |
|
||||
Compress-Archive -Path "publish/${env:PROJECT_NAME}-${env:VERSION}" -DestinationPath "release/${env:PROJECT_NAME}-${env:VERSION}.zip" -Force
|
||||
|
||||
Compress-Archive -Path "publish\$env:PROJECT_NAME-$env:VERSION\*" -DestinationPath "release\$env:PROJECT_NAME-$env:VERSION.zip" -Force
|
||||
|
||||
- name: Compress SelfContained version
|
||||
shell: pwsh
|
||||
run: |
|
||||
Compress-Archive -Path "publish/${env:PROJECT_NAME}-${env:VERSION}-SelfContained" -DestinationPath "release/${env:PROJECT_NAME}-${env:VERSION}-SelfContained.zip" -Force
|
||||
|
||||
Compress-Archive -Path "publish\$env:PROJECT_NAME-$env:VERSION-SelfContained\*" -DestinationPath "release\$env:PROJECT_NAME-$env:VERSION-SelfContained.zip" -Force
|
||||
|
||||
- name: Create GitHub Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
@@ -51,7 +85,7 @@ jobs:
|
||||
release_name: Release ${{ env.VERSION }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
|
||||
- name: Upload FrameworkDependent zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
@@ -61,7 +95,7 @@ jobs:
|
||||
asset_path: release/${{ env.PROJECT_NAME }}-${{ env.VERSION }}.zip
|
||||
asset_name: ${{ env.PROJECT_NAME }}-${{ env.VERSION }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
|
||||
- name: Upload SelfContained zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
|
||||
143
CHANGELOG.md
143
CHANGELOG.md
@@ -1,5 +1,148 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.12.17
|
||||
|
||||
- 动画边界检测的帧率提高到100帧每秒
|
||||
|
||||
## v0.12.16
|
||||
|
||||
- 导出多个时允许自动时长
|
||||
|
||||
## v0.12.15
|
||||
|
||||
- 修复附件类型枚举量字符串大小写问题
|
||||
|
||||
## v0.12.14
|
||||
|
||||
- 修复 v38 文件读取的小 bug
|
||||
|
||||
## v0.12.13
|
||||
|
||||
- 导出文件名增加额外的随机字符串
|
||||
|
||||
## v0.12.12
|
||||
|
||||
- 修复 2.1 版本遗漏的 SkinnedMeshAttachment 附件渲染
|
||||
|
||||
## v0.12.11
|
||||
|
||||
- 修复可能的闪退错误
|
||||
|
||||
## v0.12.10
|
||||
|
||||
- 增加纹理全局加载选项
|
||||
|
||||
## v0.12.9
|
||||
|
||||
- 修复由于未调用 UpdateCache 导致的约束 bug
|
||||
|
||||
## v0.12.8
|
||||
|
||||
- 增加英语界面文本
|
||||
- 增加 4.2 版本格式转换
|
||||
- 修改格式转换中一些问题和编码范式
|
||||
|
||||
## v0.12.7
|
||||
|
||||
- 修复一些问题
|
||||
|
||||
## v0.12.6
|
||||
|
||||
- 增加全屏预览
|
||||
- 增加桌面投影 (实验性功能)
|
||||
- 增加预览画面背景色设置
|
||||
- 增加分辨率和颜色预设列表
|
||||
- 皮肤面板显示 default
|
||||
|
||||
## v0.12.5
|
||||
|
||||
- 增加插槽属性面板
|
||||
- 修改皮肤属性面板设置方式为True/False
|
||||
|
||||
## v0.12.4
|
||||
|
||||
- 增加导出自动分辨率参数
|
||||
- 增加导出边缘和填充参数
|
||||
- 增加导出内容溢出参数
|
||||
- 支持3.7及以下版本多皮肤功能
|
||||
- 增加3.8版本的骨骼文件二进制和文本格式互转
|
||||
- 增加格式转换输出文件夹参数
|
||||
- 修改打开对话框的默认文件后缀筛选为所有类型
|
||||
|
||||
## v0.12.3
|
||||
|
||||
- 增加按住 ctrl 缩放选中模型
|
||||
- 增加对骨骼/网格/剪裁的调试渲染
|
||||
- 换回以前的上下参数面板布局
|
||||
- 修改窗口缩放模式为 Font -> Dpi
|
||||
- 修复部分问题
|
||||
|
||||
## v0.12.2
|
||||
|
||||
- 模型参数分标签显示
|
||||
- 皮肤/动画列表使用右键菜单进行增删
|
||||
- 标题栏显示版本号
|
||||
- 增加 webp 和 avif 动图格式
|
||||
- 增加导出参数缓存
|
||||
- 动图默认帧率修改为 24 帧
|
||||
- 增加保留最后一帧参数
|
||||
|
||||
## v0.12.1
|
||||
|
||||
- 优化使用体验, 提供初始皮肤/动画空位
|
||||
- 修复预览画面分辨率调整时父容器尺寸获取错误
|
||||
|
||||
## v0.12.0
|
||||
|
||||
- 支持皮肤列表 (仅 3.8.x 及以上支持)
|
||||
- 支持多轨道动画
|
||||
- 动画和皮肤列表多选时改为取并集
|
||||
- 修复导出时没有正确处理预乘像素的问题
|
||||
|
||||
## v0.11.5
|
||||
|
||||
- 导出格式全面支持
|
||||
- 修复预览图不显示的问题
|
||||
- 优化列表卡顿问题
|
||||
- 模型列表增加数量显示
|
||||
|
||||
## v0.11.4
|
||||
|
||||
- 增加 MP4 导出格式
|
||||
- 增加导出背景颜色参数
|
||||
- 增加日志输出 FFMpeg 参数字符串
|
||||
- 增加导出时任务栏图标执行动效
|
||||
- 修复预览面板移动模型时物理效果不同步的问题
|
||||
- 优化部分使用体验
|
||||
|
||||
## v0.11.3
|
||||
|
||||
- 增加模型隐藏设置属性
|
||||
- 加宽面板分割条 (4 -> 8 像素)
|
||||
- 优化属性面板分组显示
|
||||
- 增加调试纹理
|
||||
|
||||
## v0.11.2
|
||||
|
||||
- 增加皮肤切换
|
||||
- 优化模型缩放实现
|
||||
- 修复部分情况纹理加载异常
|
||||
|
||||
## v0.11.1
|
||||
|
||||
- 增加 GIF 导出格式
|
||||
- 增加逐个导出时可选自动时长
|
||||
- 优化使用体验
|
||||
|
||||
## v0.11.0
|
||||
|
||||
- 完成导出系统, 支持完整的单帧和帧序列导出功能
|
||||
- 预览画面增加快进功能
|
||||
|
||||
## v0.10.9
|
||||
|
||||
- 预览图导出增加名称后缀参数
|
||||
|
||||
## v0.10.8
|
||||
|
||||
- 完善预览图导出
|
||||
|
||||
141
README.en.md
141
README.en.md
@@ -1,92 +1,111 @@
|
||||
# [SpineViewer](https://github.com/ww-rm/SpineViewer)
|
||||
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
|
||||
[中文](README.md) | [English](README.en.md)
|
||||
|
||||
A simple and user-friendly tool for viewing and exporting Spine files.
|
||||
A *WYSIWYG* Spine file viewer & exporter.
|
||||
|
||||

|
||||
|
||||
---
|
||||
## Features
|
||||
|
||||
- Supports multiple Spine file versions
|
||||
- Drag & drop or copy/paste to open files in batch
|
||||
- List-based skeleton view with render layer management
|
||||
- Multi-select list to batch-adjust skeleton parameters
|
||||
- Multi-track animation support
|
||||
- Skin / custom slot attachment configuration
|
||||
- Debug rendering mode
|
||||
- Fullscreen preview
|
||||
- Export to single-frame image, animated GIF/WebP/AVIF, video formats
|
||||
- Batch export at multiple resolutions
|
||||
- Custom FFmpeg export parameters
|
||||
- …and more
|
||||
|
||||
### Spine Version Support
|
||||
|
||||
| Version | View & Export | Format Conversion | Version Conversion |
|
||||
| :------: | :-----------: | :---------------: | :----------------: |
|
||||
| `2.1.x` | :white_check_mark: | | |
|
||||
| `3.6.x` | :white_check_mark: | | |
|
||||
| `3.7.x` | :white_check_mark: | | |
|
||||
| `3.8.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.0.x` | :white_check_mark: | | |
|
||||
| `4.1.x` | :white_check_mark: | | |
|
||||
| `4.2.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.3.x` | | | |
|
||||
|
||||
More versions coming soon 🚀🚀🚀
|
||||
|
||||
### Supported Export Formats
|
||||
|
||||
| Export Format | Use Case |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| Single Frame | Generate high‑resolution still images; pick any frame manually. |
|
||||
| Frame Sequence (PNG) | Lossless PNG sequences with alpha channel preserved. |
|
||||
| GIF / WebP / AVIF | Perfect for quick animated previews. |
|
||||
| MP4 | The most widely compatible video format. |
|
||||
| WebM | Browser‑friendly streaming with optional transparency. |
|
||||
| MKV / MOV | For those who like to tinker. |
|
||||
| Custom FFmpeg Command | Use any FFmpeg arguments for complex, tailored export workflows. |
|
||||
|
||||
## Installation
|
||||
|
||||
Go to the [Release](https://github.com/ww-rm/SpineViewer/releases) page to download the compressed package.
|
||||
|
||||
The software requires the dependency framework [.NET Desktop Runtime 8.0.x](https://dotnet.microsoft.com/zh-cn/download/dotnet/8.0).
|
||||
|
||||
You can also download the package with the `SelfContained` suffix, which can run independently.
|
||||
|
||||
## Version Support
|
||||
|
||||
| Version | View & Export | Format Conversion | Version Conversion |
|
||||
| :-------: | :--------------------: | :--------------------: | :----------------: |
|
||||
| `2.1.x` | :white_check_mark: | | |
|
||||
| `3.1.x` | | | |
|
||||
| `3.4.x` | | | |
|
||||
| `3.5.x` | | | |
|
||||
| `3.6.x` | :white_check_mark: | | |
|
||||
| `3.7.x` | :white_check_mark: | | |
|
||||
| `3.8.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.1.x` | :white_check_mark: | | |
|
||||
| `4.2.x` | :white_check_mark: | | |
|
||||
| `4.3.x` | | | |
|
||||
1. Go to the [Releases](https://github.com/ww-rm/SpineViewer/releases) page and download the ZIP.
|
||||
2. Make sure you have the [.NET Desktop Runtime 8.0.x](https://dotnet.microsoft.com/download/dotnet/8.0) installed.
|
||||
3. Alternatively, download the `SelfContained` ZIP, which runs standalone without any .NET prerequisites.
|
||||
4. To export GIF or other video formats, install the `ffmpeg` CLI and add it to your PATH.
|
||||
- Windows builds: see the [FFmpeg download page](https://ffmpeg.org/download.html#build-windows)
|
||||
- Direct download: [ffmpeg-release-full.7z](https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z)
|
||||
|
||||
## Usage
|
||||
|
||||
### Importing Skeletons
|
||||
|
||||
There are 3 ways to import skeleton files:
|
||||
You can import Spine skeletons in three ways:
|
||||
|
||||
- **Drag & Drop/Paste:**
|
||||
Drag and drop or paste the skeleton file/directory into the model list.
|
||||
This method automatically searches through the provided files and subdirectories. Although convenient, it relies on the file structure and has its limitations.
|
||||
|
||||
- Only standard files with `*.json`, `*.skel`, or `.atlas` extensions are automatically detected.
|
||||
- The skeleton file and atlas file must have the same name.
|
||||
- The version string in the skeleton file must not be modified.
|
||||
- Drag & drop or paste skeleton files or folders onto the model list.
|
||||
- Use **File > Open** to batch‑open multiple skeleton files.
|
||||
- Use **File > Open Single Model** to open one at a time.
|
||||
|
||||
- **Batch Open from the File Menu:**
|
||||
This method offers more file flexibility. You can drag and drop or paste files into the file selection dialog, and additional options are available.
|
||||
|
||||
- The filename restrictions are similar to the above, but you can use the panel’s file selection button to choose skeleton files with non-standard extensions.
|
||||
- You can set a fixed load version to handle cases where the version number has been modified.
|
||||
### Adjusting Content
|
||||
|
||||
- **Open a Single Model:**
|
||||
This method offers the highest degree of freedom, allowing you to select any skeleton file and atlas file without filename restrictions. You can also set the load version.
|
||||
- Right‑click menu and keyboard shortcuts are available in the model list. You can multi‑select to adjust parameters in batch.
|
||||
- In the preview pane, you can also use mouse controls:
|
||||
- **Left‑click & drag** to move a model; hold **Ctrl** to multi‑select (synced with the list).
|
||||
- **Right‑click & drag** to pan the entire scene.
|
||||
- **Mouse wheel** to zoom; hold **Ctrl** to zoom all selected models proportionally.
|
||||
- **“Render Selected Only”** mode shows only the selected models in preview; use the list to change selection.
|
||||
|
||||
### Adjusting Preview Content
|
||||
Below the preview, playback controls let you scrub through the timeline like a basic player.
|
||||
|
||||
The model list supports right-click menus and various shortcut keys, and you can select multiple models to adjust their parameters in bulk.
|
||||
### Exporting Content
|
||||
|
||||
In addition to the parameter panel, the preview area supports several mouse actions:
|
||||
Exports follow the “what you see is what you get” principle—your real‑time preview is exactly what gets exported.
|
||||
|
||||
- **Left-click:** Select and drag models. Holding down the `Ctrl` key enables multi-selection, which syncs with the model list.
|
||||
- **Right-click:** Drag the overall canvas.
|
||||
- **Scroll wheel:** Zoom the view.
|
||||
- **Selective Rendering:** The preview area supports a mode to render only the selected models. In this mode, only the selected models are displayed, and selection changes must be made through the model list.
|
||||
Key export options:
|
||||
|
||||
In the function menu, you can reset and synchronize the animation time for all skeletons.
|
||||
- **Render Selected Only**: includes only the selected models in both preview and export.
|
||||
- **Output Folder**: if unspecified, exports go into each model’s source folder; otherwise, everything exports to the chosen folder.
|
||||
- **Export Single**: by default, each model is exported separately; enable this to render all selected models together into a single output.
|
||||
- **Auto Resolution**: ignores preview resolution and viewport size—exports at the content’s actual bounds; for animations, matches the full animation area.
|
||||
|
||||
### Exporting Preview Content
|
||||
## More
|
||||
|
||||
Both preview images and videos can be exported.
|
||||
Detailed usage and advanced tips are in the [Wiki](https://github.com/ww-rm/SpineViewer/wiki).
|
||||
Encounter a bug or have a feature request? Open an [Issue](https://github.com/ww-rm/SpineViewer/issues).
|
||||
|
||||
- **Preview Image:**
|
||||
The exported preview image shows the model in its default state, with one image per model.
|
||||
|
||||
- **Video (TODO: Currently only supports frame sequence export):**
|
||||
The complete animation duration for each skeleton can be viewed in the model parameters.
|
||||
|
||||
When the preview area is set to render only the selected models, the exported content will include only the models that are displayed.
|
||||
## Acknowledgements
|
||||
|
||||
### Format & Version Conversion
|
||||
|
||||
You can use the tools menu to convert skeleton files. This feature supports conversion between binary and text formats, as well as between different versions.
|
||||
|
||||
Currently under development, it only supports converting `3.8.x` binary format to text format.
|
||||
- [spine-runtimes](https://github.com/EsotericSoftware/spine-runtimes)
|
||||
- [SFML.Net](https://github.com/SFML/SFML.Net)
|
||||
- [FFMpegCore](https://github.com/rosenbjerg/FFMpegCore)
|
||||
|
||||
---
|
||||
|
||||
*If you like this project, please give it a :star: and share it with more people! :)*
|
||||
If you find this project useful, please give it a ⭐ and share it with others!
|
||||
|
||||
[](https://starchart.cc/ww-rm/SpineViewer)
|
||||
|
||||
109
README.md
109
README.md
@@ -1,14 +1,56 @@
|
||||
# [SpineViewer](https://github.com/ww-rm/SpineViewer)
|
||||
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
|
||||
[中文](README.md) | [English](README.en.md)
|
||||
|
||||
一个简单好用的 Spine 文件查看&导出程序.
|
||||
*所见即所得* 的 Spine 文件查看&导出程序.
|
||||
|
||||

|
||||
|
||||
---
|
||||
## 功能
|
||||
|
||||
- 支持多版本 spine 文件
|
||||
- 支持拖拽/复制粘贴批量打开文件
|
||||
- 支持列表式多骨骼查看和渲染层级管理
|
||||
- 支持列表多选批量设置骨骼参数
|
||||
- 支持多轨道动画设置
|
||||
- 支持皮肤/自定义插槽附件设置
|
||||
- 支持调试渲染
|
||||
- 支持全屏预览
|
||||
- 支持单帧/动图/视频文件导出
|
||||
- 支持自动分辨率批量导出
|
||||
- 支持 FFmpeg 自定义导出
|
||||
- ...
|
||||
|
||||
### Spine 版本支持
|
||||
|
||||
| 版本 | 查看&导出 | 格式转换 | 版本转换 |
|
||||
| :---: | :---: | :---: | :---: |
|
||||
| `2.1.x` | :white_check_mark: | | |
|
||||
| `3.6.x` | :white_check_mark: | | |
|
||||
| `3.7.x` | :white_check_mark: | | |
|
||||
| `3.8.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.0.x` | :white_check_mark: | | |
|
||||
| `4.1.x` | :white_check_mark: | | |
|
||||
| `4.2.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.3.x` | | | |
|
||||
|
||||
更多版本正在施工 :rocket: :rocket: :rocket:
|
||||
|
||||
### 导出格式支持
|
||||
|
||||
| 导出格式 | 适用场景 |
|
||||
| --- | --- |
|
||||
| 单帧画面 | 支持生成高清模型画面图像, 可手动调节需要的一帧. |
|
||||
| 帧序列 | 支持 PNG 格式帧序列, 可保留透明通道且无损压缩. |
|
||||
| GIF/WebP/AVIF | 适合生成预览动图. |
|
||||
| MP4 | 最常见的视频格式, 兼容性最好. |
|
||||
| WebM | 适合浏览器在线播放格式, 支持透明背景. |
|
||||
| MKV/MOV | 适合折腾. |
|
||||
| 自定义导出 | 除上述预设方案, 支持提供任意 FFmpeg 参数进行导出, 满足自定义复杂需求. |
|
||||
|
||||
## 安装
|
||||
|
||||
@@ -18,45 +60,19 @@
|
||||
|
||||
也可以下载带有 `SelfContained` 后缀的压缩包, 可以独立运行.
|
||||
|
||||
## 版本支持
|
||||
|
||||
| 版本 | 查看&导出 | 格式转换 | 版本转换 |
|
||||
| :---: | :---: | :---: | :---: |
|
||||
| `2.1.x` | :white_check_mark: | | |
|
||||
| `3.1.x` | | | |
|
||||
| `3.4.x` | | | |
|
||||
| `3.5.x` | | | |
|
||||
| `3.6.x` | :white_check_mark: | | |
|
||||
| `3.7.x` | :white_check_mark: | | |
|
||||
| `3.8.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.1.x` | :white_check_mark: | | |
|
||||
| `4.2.x` | :white_check_mark: | | |
|
||||
| `4.3.x` | | | |
|
||||
导出 GIF 等视频格式需要在本地安装 ffmpeg 命令行, 并且添加至环境变量, [点击前往 FFmpeg-Windows 下载页面](https://ffmpeg.org/download.html#build-windows), 也可以点这个下载最新版本 [ffmpeg-release-full.7z](https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z).
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 骨骼导入
|
||||
|
||||
有 3 种模式导入骨骼文件:
|
||||
有 3 种方式导入骨骼文件:
|
||||
|
||||
- 拖放/粘贴需要导入的骨骼文件/目录到模型列表
|
||||
|
||||
这种方式会自动查找传入的文件列表以及目录内的子级文件列表, 虽然方便但是依赖模型文件结构, 限制最多.
|
||||
|
||||
- 仅支持自动发现标准的 `*.json`/`*.skel`/`.atlas` 后缀文件.
|
||||
- 骨骼文件和 atlas 文件需要是同名.
|
||||
- 需要保证骨骼文件里的版本字符串不是魔改过的.
|
||||
- 从文件菜单里批量打开骨骼文件
|
||||
- 从文件菜单选择单个模型打开
|
||||
|
||||
这种方式提供一定程度的文件自由度, 文件选择框里同样支持拖放/粘贴, 但是多一些额外选项.
|
||||
|
||||
- 文件名限制条件与上面类似, 但是可以通过面板的选择文件按钮选择非标准后缀的骨骼文件.
|
||||
- 可以设置固定加载版本, 便于应对魔改过的版本号.
|
||||
- 选择单个模型打开
|
||||
|
||||
这种方式自由度最高, 允许选择任意的骨骼文件和 atlas 文件, 可以没有文件名限制, 并且也可以设置加载版本.
|
||||
|
||||
### 预览内容调整
|
||||
### 内容调整
|
||||
|
||||
模型列表支持右键菜单以及部分快捷键, 并且可以多选进行模型参数的批量调整.
|
||||
|
||||
@@ -64,27 +80,34 @@
|
||||
|
||||
- 左键可以选择和拖拽模型, 按下 `Ctrl` 键可以实现多选, 与左侧列表选择是联动的.
|
||||
- 右键对整体画面进行拖动.
|
||||
- 滚轮进行画面缩放.
|
||||
- 预览画面支持仅渲染选中, 在该模式下, 画面仅显示被选中的模型, 并且只能通过左侧列表改变选中状态.
|
||||
- 滚轮进行画面缩放, 按住 `Ctrl` 可以对选中的模型进行批量缩放.
|
||||
- 仅渲染选中模式, 在该模式下, 预览画面仅包含被选中的模型, 并且只能通过左侧列表改变选中状态.
|
||||
|
||||
在功能菜单中, 可以重置同步所有骨骼动画时间.
|
||||
预览画面下方按钮支持对画面时间进行调整, 可以当作一个简易的播放器.
|
||||
|
||||
### 预览内容导出
|
||||
### 内容导出
|
||||
|
||||
支持预览图和视频的导出.
|
||||
导出遵循 "所见即所得" 原则, 即实时预览的画面就是你导出的画面.
|
||||
|
||||
预览图导出的内容是模型的默认状态画面, 每个模型一张单独的预览图.
|
||||
导出有以下几个关键参数:
|
||||
|
||||
视频(TODO: 目前仅支持帧序列导出), 可以在每个骨骼的模型参数中查看动画完整时长.
|
||||
- 仅渲染选中. 这个参数不仅影响预览模式, 也影响导出, 如果仅渲染选中, 那么在导出时只有被选中的模型会被考虑, 忽略其他模型.
|
||||
- 输出文件夹. 这个参数某些时候可选, 当不提供时, 则将输出产物输出到每个模型各自的模型文件夹, 否则输出产物全部输出到提供的输出文件夹.
|
||||
- 导出单个. 默认是每个模型独立导出, 即对模型列表进行批量操作, 如果选择仅导出单个, 那么被导出的所有模型将在同一个画面上被渲染, 输出产物只有一份.
|
||||
- 自动分辨率. 该模式会忽略预览画面的分辨率和视区参数, 导出产物的分辨率与被导出内容的实际大小一致, 如果是动图或者视频则会与完整显示动画的必需大小一致.
|
||||
|
||||
当预览画面处于仅渲染选中状态时, 导出的内容仅包含被选中的模型, 也就是在画面中显示的内容.
|
||||
### 更多
|
||||
|
||||
### 格式与版本转换
|
||||
更为详细的使用方法和说明见 [Wiki](https://github.com/ww-rm/SpineViewer/wiki), 有使用上的问题或者 BUG 可以提个 [Issue](https://github.com/ww-rm/SpineViewer/issues).
|
||||
|
||||
可以通过工具菜单进行骨骼文件换, 允许二进制和文本格式之间的转换, 以及不同版本间的转换.
|
||||
## Acknowledgements
|
||||
|
||||
目前处于施工中, 仅支持转换 `3.8.x` 二进制到文本格式.
|
||||
- [spine-runtimes](https://github.com/EsotericSoftware/spine-runtimes)
|
||||
- [SFML.Net](https://github.com/SFML/SFML.Net)
|
||||
- [FFMpegCore](https://github.com/rosenbjerg/FFMpegCore)
|
||||
|
||||
---
|
||||
|
||||
*如果你觉得这个项目不错请给个 :star:, 并分享给更多人知道! :)*
|
||||
|
||||
[](https://starchart.cc/ww-rm/SpineViewer)
|
||||
|
||||
@@ -41,8 +41,9 @@ namespace SpineRuntime21 {
|
||||
|
||||
public AnimationStateData Data { get { return data; } }
|
||||
public float TimeScale { get { return timeScale; } set { timeScale = value; } }
|
||||
public List<TrackEntry> Tracks => tracks;
|
||||
|
||||
public delegate void StartEndDelegate(AnimationState state, int trackIndex);
|
||||
public delegate void StartEndDelegate(AnimationState state, int trackIndex);
|
||||
public event StartEndDelegate Start;
|
||||
public event StartEndDelegate End;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class Bone{
|
||||
static public bool yDown;
|
||||
static readonly public bool yDown = false;
|
||||
|
||||
internal BoneData data;
|
||||
internal Skeleton skeleton;
|
||||
@@ -84,7 +84,8 @@ namespace SpineRuntime21 {
|
||||
|
||||
/// <summary>Computes the world SRT using the parent bone and the local SRT.</summary>
|
||||
public void UpdateWorldTransform () {
|
||||
Bone parent = this.parent;
|
||||
float sx = skeleton.scaleX, sy = skeleton.scaleY;
|
||||
Bone parent = this.parent;
|
||||
float x = this.x, y = this.y;
|
||||
if (parent != null) {
|
||||
worldX = x * parent.m00 + y * parent.m01 + parent.worldX;
|
||||
@@ -100,34 +101,22 @@ namespace SpineRuntime21 {
|
||||
worldFlipX = parent.worldFlipX != flipX;
|
||||
worldFlipY = parent.worldFlipY != flipY;
|
||||
} else {
|
||||
Skeleton skeleton = this.skeleton;
|
||||
bool skeletonFlipX = skeleton.flipX, skeletonFlipY = skeleton.flipY;
|
||||
worldX = skeletonFlipX ? -x : x;
|
||||
worldY = skeletonFlipY != yDown ? -y : y;
|
||||
worldX = x * sx;
|
||||
worldY = y * sy;
|
||||
worldScaleX = scaleX;
|
||||
worldScaleY = scaleY;
|
||||
worldRotation = rotationIK;
|
||||
worldFlipX = skeletonFlipX != flipX;
|
||||
worldFlipY = skeletonFlipY != flipY;
|
||||
worldFlipX = (sx < 0) != flipX;
|
||||
worldFlipY = (sy < 0) != flipY;
|
||||
}
|
||||
float radians = worldRotation * (float)Math.PI / 180;
|
||||
float cos = (float)Math.Cos(radians);
|
||||
float sin = (float)Math.Sin(radians);
|
||||
if (worldFlipX) {
|
||||
m00 = -cos * worldScaleX;
|
||||
m01 = sin * worldScaleY;
|
||||
} else {
|
||||
m00 = cos * worldScaleX;
|
||||
m01 = -sin * worldScaleY;
|
||||
}
|
||||
if (worldFlipY != yDown) {
|
||||
m10 = -sin * worldScaleX;
|
||||
m11 = -cos * worldScaleY;
|
||||
} else {
|
||||
m10 = sin * worldScaleX;
|
||||
m11 = cos * worldScaleY;
|
||||
}
|
||||
}
|
||||
m00 = cos * worldScaleX * sx;
|
||||
m01 = -sin * worldScaleY * sx;
|
||||
m10 = sin * worldScaleX * sy;
|
||||
m11 = cos * worldScaleY * sy;
|
||||
}
|
||||
|
||||
public void SetToSetupPose () {
|
||||
BoneData data = this.data;
|
||||
|
||||
@@ -42,8 +42,8 @@ namespace SpineRuntime21 {
|
||||
internal Skin skin;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
internal float time;
|
||||
internal bool flipX, flipY;
|
||||
internal float x, y;
|
||||
internal float scaleX = 1, scaleY = 1;
|
||||
internal float x, y;
|
||||
|
||||
public SkeletonData Data { get { return data; } }
|
||||
public List<Bone> Bones { get { return bones; } }
|
||||
@@ -58,10 +58,16 @@ namespace SpineRuntime21 {
|
||||
public float Time { get { return time; } set { time = value; } }
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
public bool FlipX { get { return flipX; } set { flipX = value; } }
|
||||
public bool FlipY { get { return flipY; } set { flipY = value; } }
|
||||
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
|
||||
public Bone RootBone {
|
||||
[Obsolete("Use ScaleX instead. FlipX is when ScaleX is negative.")]
|
||||
public bool FlipX { get { return scaleX < 0; } set { scaleX = value ? -1f : 1f; } }
|
||||
|
||||
[Obsolete("Use ScaleY instead. FlipY is when ScaleY is negative.")]
|
||||
public bool FlipY { get { return scaleY < 0; } set { scaleY = value ? -1f : 1f; } }
|
||||
|
||||
public Bone RootBone {
|
||||
get {
|
||||
return bones.Count == 0 ? null : bones[0];
|
||||
}
|
||||
@@ -302,5 +308,50 @@ namespace SpineRuntime21 {
|
||||
public void Update (float delta) {
|
||||
time += delta;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetBounds(out float x, out float y, out float width, out float height)
|
||||
{
|
||||
float[] temp = new float[8];
|
||||
float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
|
||||
for (int i = 0, n = drawOrder.Count; i < n; i++)
|
||||
{
|
||||
Slot slot = drawOrder[i];
|
||||
int verticesLength = 0;
|
||||
float[] vertices = null;
|
||||
Attachment attachment = slot.Attachment;
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
verticesLength = 8;
|
||||
vertices = temp;
|
||||
if (vertices.Length < 8) vertices = temp = new float[8];
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, temp);
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
|
||||
MeshAttachment mesh = meshAttachment;
|
||||
verticesLength = mesh.Vertices.Length;
|
||||
vertices = temp;
|
||||
if (vertices.Length < verticesLength) vertices = temp = new float[verticesLength];
|
||||
mesh.ComputeWorldVertices(slot, temp);
|
||||
}
|
||||
|
||||
if (vertices != null)
|
||||
{
|
||||
for (int ii = 0; ii < verticesLength; ii += 2)
|
||||
{
|
||||
float vx = vertices[ii], vy = vertices[ii + 1];
|
||||
minX = Math.Min(minX, vx);
|
||||
minY = Math.Min(minY, vy);
|
||||
maxX = Math.Max(maxX, vx);
|
||||
maxY = Math.Max(maxY, vy);
|
||||
}
|
||||
}
|
||||
}
|
||||
x = minX;
|
||||
y = minY;
|
||||
width = maxX - minX;
|
||||
height = maxY - minY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,9 @@ namespace SpineRuntime21 {
|
||||
new Dictionary<KeyValuePair<int, String>, Attachment>(AttachmentComparer.Instance);
|
||||
|
||||
public String Name { get { return name; } }
|
||||
public Dictionary<KeyValuePair<int, String>, Attachment> Attachments { get { return attachments; } }
|
||||
|
||||
public Skin (String name) {
|
||||
public Skin (String name) {
|
||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>2.1.25</Version>
|
||||
|
||||
@@ -152,27 +152,13 @@ namespace SpineRuntime36 {
|
||||
|
||||
Bone parent = this.parent;
|
||||
if (parent == null) { // Root bone.
|
||||
float rotationY = rotation + 90 + shearY;
|
||||
float la = MathUtils.CosDeg(rotation + shearX) * scaleX;
|
||||
float lb = MathUtils.CosDeg(rotationY) * scaleY;
|
||||
float lc = MathUtils.SinDeg(rotation + shearX) * scaleX;
|
||||
float ld = MathUtils.SinDeg(rotationY) * scaleY;
|
||||
if (skeleton.flipX) {
|
||||
x = -x;
|
||||
la = -la;
|
||||
lb = -lb;
|
||||
}
|
||||
if (skeleton.flipY != yDown) {
|
||||
y = -y;
|
||||
lc = -lc;
|
||||
ld = -ld;
|
||||
}
|
||||
a = la;
|
||||
b = lb;
|
||||
c = lc;
|
||||
d = ld;
|
||||
worldX = x + skeleton.x;
|
||||
worldY = y + skeleton.y;
|
||||
float rotationY = rotation + 90 + shearY, sx = skeleton.scaleX, sy = skeleton.scaleY;
|
||||
a = MathUtils.CosDeg(rotation + shearX) * scaleX * sx;
|
||||
b = MathUtils.CosDeg(rotationY) * scaleY * sx;
|
||||
c = MathUtils.SinDeg(rotation + shearX) * scaleX * sy;
|
||||
d = MathUtils.SinDeg(rotationY) * scaleY * sy;
|
||||
worldX = x * sx + skeleton.x;
|
||||
worldY = y * sy + skeleton.y;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,13 +214,16 @@ namespace SpineRuntime36 {
|
||||
case TransformMode.NoScale:
|
||||
case TransformMode.NoScaleOrReflection: {
|
||||
float cos = MathUtils.CosDeg(rotation), sin = MathUtils.SinDeg(rotation);
|
||||
float za = pa * cos + pb * sin;
|
||||
float zc = pc * cos + pd * sin;
|
||||
float za = (pa * cos + pb * sin) / skeleton.scaleX;
|
||||
float zc = (pc * cos + pd * sin) / skeleton.scaleY;
|
||||
float s = (float)Math.Sqrt(za * za + zc * zc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
za *= s;
|
||||
zc *= s;
|
||||
s = (float)Math.Sqrt(za * za + zc * zc);
|
||||
if (data.transformMode == TransformMode.NoScale
|
||||
&& (pa * pd - pb * pc < 0) != (skeleton.scaleX < 0 != skeleton.scaleY < 0)) s = -s;
|
||||
|
||||
float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za);
|
||||
float zb = MathUtils.Cos(r) * s;
|
||||
float zd = MathUtils.Sin(r) * s;
|
||||
@@ -242,26 +231,18 @@ namespace SpineRuntime36 {
|
||||
float lb = MathUtils.CosDeg(90 + shearY) * scaleY;
|
||||
float lc = MathUtils.SinDeg(shearX) * scaleX;
|
||||
float ld = MathUtils.SinDeg(90 + shearY) * scaleY;
|
||||
if (data.transformMode != TransformMode.NoScaleOrReflection? pa * pd - pb* pc< 0 : skeleton.flipX != skeleton.flipY) {
|
||||
zb = -zb;
|
||||
zd = -zd;
|
||||
}
|
||||
a = za * la + zb * lc;
|
||||
b = za * lb + zb * ld;
|
||||
c = zc * la + zd * lc;
|
||||
d = zc * lb + zd * ld;
|
||||
return;
|
||||
d = zc * lb + zd * ld;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skeleton.flipX) {
|
||||
a = -a;
|
||||
b = -b;
|
||||
}
|
||||
if (skeleton.flipY != Bone.yDown) {
|
||||
c = -c;
|
||||
d = -d;
|
||||
}
|
||||
a *= skeleton.scaleX;
|
||||
b *= skeleton.scaleX;
|
||||
c *= skeleton.scaleY;
|
||||
d *= skeleton.scaleY;
|
||||
}
|
||||
|
||||
public void SetToSetupPose () {
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace SpineRuntime36 {
|
||||
internal Skin skin;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
internal float time;
|
||||
internal bool flipX, flipY;
|
||||
internal float x, y;
|
||||
internal float scaleX = 1, scaleY = 1;
|
||||
internal float x, y;
|
||||
|
||||
public SkeletonData Data { get { return data; } }
|
||||
public ExposedList<Bone> Bones { get { return bones; } }
|
||||
@@ -64,10 +64,16 @@ namespace SpineRuntime36 {
|
||||
public float Time { get { return time; } set { time = value; } }
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
public bool FlipX { get { return flipX; } set { flipX = value; } }
|
||||
public bool FlipY { get { return flipY; } set { flipY = value; } }
|
||||
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
|
||||
public Bone RootBone {
|
||||
[Obsolete("Use ScaleX instead. FlipX is when ScaleX is negative.")]
|
||||
public bool FlipX { get { return scaleX < 0; } set { scaleX = value ? -1f : 1f; } }
|
||||
|
||||
[Obsolete("Use ScaleY instead. FlipY is when ScaleY is negative.")]
|
||||
public bool FlipY { get { return scaleY < 0; } set { scaleY = value ? -1f : 1f; } }
|
||||
|
||||
public Bone RootBone {
|
||||
get { return bones.Count == 0 ? null : bones.Items[0]; }
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.6.53</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.7.94</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.8.99</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.0.64</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.1.54</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.2.74</Version>
|
||||
|
||||
6
SpineViewer/App.config
Normal file
6
SpineViewer/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="localize" value="zh-CN"/>
|
||||
</appSettings>
|
||||
</configuration>
|
||||
71
SpineViewer/Controls/SkelFileListBox.Designer.cs
generated
71
SpineViewer/Controls/SkelFileListBox.Designer.cs
generated
@@ -29,6 +29,7 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SkelFileListBox));
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
flowLayoutPanel1 = new FlowLayoutPanel();
|
||||
button_AddFolder = new Button();
|
||||
@@ -48,129 +49,91 @@
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.ColumnCount = 1;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(flowLayoutPanel1, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(listBox, 0, 1);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 2;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.Size = new Size(801, 394);
|
||||
tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// flowLayoutPanel1
|
||||
//
|
||||
flowLayoutPanel1.AutoSize = true;
|
||||
flowLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1");
|
||||
flowLayoutPanel1.Controls.Add(button_AddFolder);
|
||||
flowLayoutPanel1.Controls.Add(button_AddFile);
|
||||
flowLayoutPanel1.Controls.Add(label_Tip);
|
||||
flowLayoutPanel1.Dock = DockStyle.Fill;
|
||||
flowLayoutPanel1.Location = new Point(3, 3);
|
||||
flowLayoutPanel1.Name = "flowLayoutPanel1";
|
||||
flowLayoutPanel1.Size = new Size(795, 40);
|
||||
flowLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// button_AddFolder
|
||||
//
|
||||
button_AddFolder.AutoSize = true;
|
||||
button_AddFolder.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_AddFolder.Location = new Point(3, 3);
|
||||
resources.ApplyResources(button_AddFolder, "button_AddFolder");
|
||||
button_AddFolder.Name = "button_AddFolder";
|
||||
button_AddFolder.Size = new Size(122, 34);
|
||||
button_AddFolder.TabIndex = 0;
|
||||
button_AddFolder.Text = "添加文件夹...";
|
||||
button_AddFolder.UseVisualStyleBackColor = true;
|
||||
button_AddFolder.Click += button_AddFolder_Click;
|
||||
//
|
||||
// button_AddFile
|
||||
//
|
||||
button_AddFile.AutoSize = true;
|
||||
button_AddFile.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_AddFile.Location = new Point(131, 3);
|
||||
resources.ApplyResources(button_AddFile, "button_AddFile");
|
||||
button_AddFile.Name = "button_AddFile";
|
||||
button_AddFile.Size = new Size(104, 34);
|
||||
button_AddFile.TabIndex = 1;
|
||||
button_AddFile.Text = "添加文件...";
|
||||
button_AddFile.UseVisualStyleBackColor = true;
|
||||
button_AddFile.Click += button_AddFile_Click;
|
||||
//
|
||||
// label_Tip
|
||||
//
|
||||
label_Tip.Anchor = AnchorStyles.Left;
|
||||
label_Tip.AutoSize = true;
|
||||
label_Tip.Location = new Point(241, 8);
|
||||
resources.ApplyResources(label_Tip, "label_Tip");
|
||||
label_Tip.Name = "label_Tip";
|
||||
label_Tip.Size = new Size(139, 24);
|
||||
label_Tip.TabIndex = 3;
|
||||
label_Tip.Text = "已添加 0 个文件";
|
||||
label_Tip.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// listBox
|
||||
//
|
||||
resources.ApplyResources(listBox, "listBox");
|
||||
listBox.AllowDrop = true;
|
||||
listBox.ContextMenuStrip = contextMenuStrip;
|
||||
listBox.Dock = DockStyle.Fill;
|
||||
listBox.FormattingEnabled = true;
|
||||
listBox.HorizontalScrollbar = true;
|
||||
listBox.ItemHeight = 24;
|
||||
listBox.Location = new Point(3, 49);
|
||||
listBox.Name = "listBox";
|
||||
listBox.SelectionMode = SelectionMode.MultiExtended;
|
||||
listBox.Size = new Size(795, 342);
|
||||
listBox.TabIndex = 0;
|
||||
listBox.DragDrop += listBox_DragDrop;
|
||||
listBox.DragEnter += listBox_DragEnter;
|
||||
//
|
||||
// contextMenuStrip
|
||||
//
|
||||
resources.ApplyResources(contextMenuStrip, "contextMenuStrip");
|
||||
contextMenuStrip.ImageScalingSize = new Size(24, 24);
|
||||
contextMenuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_SelectAll, toolStripMenuItem_Paste, toolStripMenuItem_Remove });
|
||||
contextMenuStrip.Name = "contextMenuStrip";
|
||||
contextMenuStrip.Size = new Size(184, 94);
|
||||
//
|
||||
// toolStripMenuItem_SelectAll
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_SelectAll, "toolStripMenuItem_SelectAll");
|
||||
toolStripMenuItem_SelectAll.Name = "toolStripMenuItem_SelectAll";
|
||||
toolStripMenuItem_SelectAll.ShortcutKeys = Keys.Control | Keys.A;
|
||||
toolStripMenuItem_SelectAll.Size = new Size(183, 30);
|
||||
toolStripMenuItem_SelectAll.Text = "全选";
|
||||
toolStripMenuItem_SelectAll.Click += toolStripMenuItem_SelectAll_Click;
|
||||
//
|
||||
// toolStripMenuItem_Paste
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Paste, "toolStripMenuItem_Paste");
|
||||
toolStripMenuItem_Paste.Name = "toolStripMenuItem_Paste";
|
||||
toolStripMenuItem_Paste.ShortcutKeys = Keys.Control | Keys.V;
|
||||
toolStripMenuItem_Paste.Size = new Size(183, 30);
|
||||
toolStripMenuItem_Paste.Text = "粘贴";
|
||||
toolStripMenuItem_Paste.Click += toolStripMenuItem_Paste_Click;
|
||||
//
|
||||
// toolStripMenuItem_Remove
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Remove, "toolStripMenuItem_Remove");
|
||||
toolStripMenuItem_Remove.Name = "toolStripMenuItem_Remove";
|
||||
toolStripMenuItem_Remove.ShortcutKeys = Keys.Delete;
|
||||
toolStripMenuItem_Remove.Size = new Size(183, 30);
|
||||
toolStripMenuItem_Remove.Text = "移除";
|
||||
toolStripMenuItem_Remove.Click += toolStripMenuItem_Remove_Click;
|
||||
//
|
||||
// folderBrowserDialog
|
||||
//
|
||||
resources.ApplyResources(folderBrowserDialog, "folderBrowserDialog");
|
||||
//
|
||||
// openFileDialog_Skel
|
||||
//
|
||||
openFileDialog_Skel.AddExtension = false;
|
||||
openFileDialog_Skel.AddToRecent = false;
|
||||
openFileDialog_Skel.Filter = "skel 文件 (*.skel; *.json)|*.skel;*.json|二进制文件 (*.skel)|*.skel|文本文件 (*.json)|*.json|所有文件 (*.*)|*.*";
|
||||
resources.ApplyResources(openFileDialog_Skel, "openFileDialog_Skel");
|
||||
openFileDialog_Skel.Multiselect = true;
|
||||
openFileDialog_Skel.Title = "批量选择skel文件";
|
||||
//
|
||||
// SkelFileListBox
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(tableLayoutPanel1);
|
||||
Name = "SkelFileListBox";
|
||||
Size = new Size(801, 394);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
flowLayoutPanel1.ResumeLayout(false);
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using SpineViewer.Spine;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
@@ -16,13 +17,14 @@ namespace SpineViewer.Controls
|
||||
public SkelFileListBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
Items = listBox.Items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ListBox.Items
|
||||
/// </summary>
|
||||
public readonly ListBox.ObjectCollection Items;
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public ListBox.ObjectCollection Items { get => listBox.Items; }
|
||||
|
||||
/// <summary>
|
||||
/// 从路径列表添加
|
||||
@@ -33,14 +35,14 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower()))
|
||||
if (SpineUtils.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower()))
|
||||
listBox.Items.Add(Path.GetFullPath(path));
|
||||
}
|
||||
else if (Directory.Exists(path))
|
||||
{
|
||||
foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
if (SpineUtils.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
listBox.Items.Add(file);
|
||||
}
|
||||
}
|
||||
@@ -57,12 +59,12 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
if (SpineUtils.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
listBox.Items.Add(file);
|
||||
}
|
||||
}
|
||||
|
||||
label_Tip.Text = $"已选择 {listBox.Items.Count} 个文件";
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
|
||||
private void button_AddFile_Click(object sender, EventArgs e)
|
||||
@@ -73,7 +75,7 @@ namespace SpineViewer.Controls
|
||||
foreach (var p in openFileDialog_Skel.FileNames)
|
||||
listBox.Items.Add(Path.GetFullPath(p));
|
||||
|
||||
label_Tip.Text = $"已选择 {listBox.Items.Count} 个文件";
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
|
||||
private void listBox_DragEnter(object sender, DragEventArgs e)
|
||||
@@ -90,7 +92,7 @@ namespace SpineViewer.Controls
|
||||
return;
|
||||
|
||||
AddFromFileDrop((string[])e.Data.GetData(DataFormats.FileDrop));
|
||||
label_Tip.Text = $"已选择 {listBox.Items.Count} 个文件";
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_SelectAll_Click(object sender, EventArgs e)
|
||||
@@ -108,7 +110,7 @@ namespace SpineViewer.Controls
|
||||
var paths = new string[fileDropList.Count];
|
||||
fileDropList.CopyTo(paths, 0);
|
||||
AddFromFileDrop(paths);
|
||||
label_Tip.Text = $"已选择 {listBox.Items.Count} 个文件";
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Remove_Click(object sender, EventArgs e)
|
||||
@@ -117,7 +119,7 @@ namespace SpineViewer.Controls
|
||||
listBox.SelectedIndices.CopyTo(indices, 0);
|
||||
for (int i = indices.Length - 1; i >= 0; i--)
|
||||
listBox.Items.RemoveAt(indices[i]);
|
||||
label_Tip.Text = $"已选择 {listBox.Items.Count} 个文件";
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
219
SpineViewer/Controls/SkelFileListBox.en.resx
Normal file
219
SpineViewer/Controls/SkelFileListBox.en.resx
Normal file
@@ -0,0 +1,219 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 2</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="flowLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>796, 38</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>224, 94</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="listBox.ItemHeight" type="System.Int32, mscorlib">
|
||||
<value>24</value>
|
||||
</data>
|
||||
<data name="listBox.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 44</value>
|
||||
</data>
|
||||
<data name="listBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="listBox.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>796, 348</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>802, 394</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>129, 34</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Text" xml:space="preserve">
|
||||
<value>Add Folder...</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>138, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>112, 34</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Text" xml:space="preserve">
|
||||
<value>Add Files...</value>
|
||||
</data>
|
||||
<data name="label_Tip.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>256, 7</value>
|
||||
</data>
|
||||
<data name="label_Tip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>117, 24</value>
|
||||
</data>
|
||||
<data name="label_Tip.Text" xml:space="preserve">
|
||||
<value>0 file added.</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>223, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Text" xml:space="preserve">
|
||||
<value>Select all</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>223, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.Text" xml:space="preserve">
|
||||
<value>Paste</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>223, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
|
||||
<value>Remove</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Filter" xml:space="preserve">
|
||||
<value>All files (*.*)|*.*|Skel files (*.skel; *.json)|*.skel;*.json</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Title" xml:space="preserve">
|
||||
<value>Select .skel files</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>11, 24</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>802, 394</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,13 +117,308 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>556, 18</value>
|
||||
</metadata>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Filter" xml:space="preserve">
|
||||
<value>所有文件 (*.*)|*.*|skel 文件 (*.skel; *.json)|*.skel;*.json</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="button_AddFolder.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>104, 30</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="listBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Name" xml:space="preserve">
|
||||
<value>label_Tip</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="button_AddFile.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>button_AddFile.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="toolStripMenuItem_Remove.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Del</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>button_AddFolder.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="listBox.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="listBox.HorizontalScrollbar" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_SelectAll.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_SelectAll</value>
|
||||
</data>
|
||||
<data name=">>listBox.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 2</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Text" xml:space="preserve">
|
||||
<value>添加文件...</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_SelectAll.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label_Tip.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>202, 7</value>
|
||||
</data>
|
||||
<data name=">>button_AddFolder.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>161, 24</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>110, 2</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+A</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Paste.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Paste</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_AddFolder.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>162, 76</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>listBox.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label_Tip.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleCenter</value>
|
||||
</data>
|
||||
<data name="label_Tip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>115, 20</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Text" xml:space="preserve">
|
||||
<value>全选</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>folderBrowserDialog.Name" xml:space="preserve">
|
||||
<value>folderBrowserDialog</value>
|
||||
</data>
|
||||
<data name="label_Tip.Text" xml:space="preserve">
|
||||
<value>已添加 0 个文件</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="listBox.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>579, 286</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+V</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Remove.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>listBox.Name" xml:space="preserve">
|
||||
<value>listBox</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="listBox.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>listBox.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ListBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.Text" xml:space="preserve">
|
||||
<value>粘贴</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>583, 328</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>88, 30</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>button_AddFile.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Title" xml:space="preserve">
|
||||
<value>批量选择skel文件</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>button_AddFile.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_AddFile.Name" xml:space="preserve">
|
||||
<value>button_AddFile</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
|
||||
<value>移除</value>
|
||||
</data>
|
||||
<data name="button_AddFile.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Paste.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button_AddFolder.Name" xml:space="preserve">
|
||||
<value>button_AddFolder</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Skel.Name" xml:space="preserve">
|
||||
<value>openFileDialog_Skel</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Text" xml:space="preserve">
|
||||
<value>添加文件夹...</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="label_Tip.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>583, 328</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>SkelFileListBox</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="listBox.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 40</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 2</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip.Name" xml:space="preserve">
|
||||
<value>contextMenuStrip</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>579, 34</value>
|
||||
</data>
|
||||
<data name="label_Tip.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Skel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Remove.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Remove</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>161, 24</value>
|
||||
</data>
|
||||
<data name="label_Tip.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name="button_AddFile.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>161, 24</value>
|
||||
</data>
|
||||
<data name=">>folderBrowserDialog.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.FolderBrowserDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label_Tip.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="flowLayoutPanel1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="listBox" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,Percent,100" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<metadata name="folderBrowserDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>286, 21</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>556, 18</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog_Skel.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>31, 27</value>
|
||||
<value>30, 21</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
147
SpineViewer/Controls/SpineListView.Designer.cs
generated
147
SpineViewer/Controls/SpineListView.Designer.cs
generated
@@ -29,6 +29,7 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpineListView));
|
||||
listView = new ListView();
|
||||
columnHeader_Name = new ColumnHeader();
|
||||
contextMenuStrip = new ContextMenuStrip(components);
|
||||
@@ -44,8 +45,9 @@
|
||||
toolStripMenuItem_MoveTop = new ToolStripMenuItem();
|
||||
toolStripMenuItem_MoveBottom = new ToolStripMenuItem();
|
||||
toolStripSeparator3 = new ToolStripSeparator();
|
||||
toolStripMenuItem_SelectAll = new ToolStripMenuItem();
|
||||
toolStripMenuItem_CopyPreview = new ToolStripMenuItem();
|
||||
toolStripMenuItem_AddFromClipboard = new ToolStripMenuItem();
|
||||
toolStripMenuItem_SelectAll = new ToolStripMenuItem();
|
||||
toolStripSeparator4 = new ToolStripSeparator();
|
||||
toolStripMenuItem_ChangeView = new ToolStripMenuItem();
|
||||
toolStripMenuItem_LargeIconView = new ToolStripMenuItem();
|
||||
@@ -53,26 +55,27 @@
|
||||
toolStripMenuItem_DetailsView = new ToolStripMenuItem();
|
||||
imageList_LargeIcon = new ImageList(components);
|
||||
imageList_SmallIcon = new ImageList(components);
|
||||
toolStripMenuItem_AddFromClipboard = new ToolStripMenuItem();
|
||||
timer_SelectedIndexChangedDebounce = new System.Windows.Forms.Timer(components);
|
||||
statusStrip = new StatusStrip();
|
||||
toolStripStatusLabel_CountInfo = new ToolStripStatusLabel();
|
||||
tableLayoutPanel = new TableLayoutPanel();
|
||||
contextMenuStrip.SuspendLayout();
|
||||
statusStrip.SuspendLayout();
|
||||
tableLayoutPanel.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// listView
|
||||
//
|
||||
listView.Alignment = ListViewAlignment.Left;
|
||||
resources.ApplyResources(listView, "listView");
|
||||
listView.AllowDrop = true;
|
||||
listView.Columns.AddRange(new ColumnHeader[] { columnHeader_Name });
|
||||
listView.ContextMenuStrip = contextMenuStrip;
|
||||
listView.Dock = DockStyle.Fill;
|
||||
listView.FullRowSelect = true;
|
||||
listView.GridLines = true;
|
||||
listView.LargeImageList = imageList_LargeIcon;
|
||||
listView.Location = new Point(0, 0);
|
||||
listView.Name = "listView";
|
||||
listView.ShowItemToolTips = true;
|
||||
listView.Size = new Size(336, 445);
|
||||
listView.SmallImageList = imageList_SmallIcon;
|
||||
listView.TabIndex = 1;
|
||||
listView.UseCompatibleStateImageBehavior = false;
|
||||
listView.View = View.Details;
|
||||
listView.ItemDrag += listView_ItemDrag;
|
||||
@@ -83,181 +86,181 @@
|
||||
//
|
||||
// columnHeader_Name
|
||||
//
|
||||
columnHeader_Name.Text = "名称";
|
||||
columnHeader_Name.Width = 220;
|
||||
resources.ApplyResources(columnHeader_Name, "columnHeader_Name");
|
||||
//
|
||||
// contextMenuStrip
|
||||
//
|
||||
resources.ApplyResources(contextMenuStrip, "contextMenuStrip");
|
||||
contextMenuStrip.ImageScalingSize = new Size(24, 24);
|
||||
contextMenuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_Add, toolStripMenuItem_Insert, toolStripMenuItem_Remove, toolStripSeparator1, toolStripMenuItem_BatchAdd, toolStripMenuItem_RemoveAll, toolStripSeparator2, toolStripMenuItem_MoveUp, toolStripMenuItem_MoveDown, toolStripMenuItem_MoveTop, toolStripMenuItem_MoveBottom, toolStripSeparator3, toolStripMenuItem_CopyPreview, toolStripMenuItem_AddFromClipboard, toolStripMenuItem_SelectAll, toolStripSeparator4, toolStripMenuItem_ChangeView });
|
||||
contextMenuStrip.Name = "contextMenuStrip";
|
||||
contextMenuStrip.Size = new Size(329, 451);
|
||||
contextMenuStrip.Closed += contextMenuStrip_Closed;
|
||||
contextMenuStrip.Opening += contextMenuStrip_Opening;
|
||||
//
|
||||
// toolStripMenuItem_Add
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Add, "toolStripMenuItem_Add");
|
||||
toolStripMenuItem_Add.Name = "toolStripMenuItem_Add";
|
||||
toolStripMenuItem_Add.Size = new Size(328, 30);
|
||||
toolStripMenuItem_Add.Text = "添加...";
|
||||
toolStripMenuItem_Add.Click += toolStripMenuItem_Add_Click;
|
||||
//
|
||||
// toolStripMenuItem_Insert
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Insert, "toolStripMenuItem_Insert");
|
||||
toolStripMenuItem_Insert.Name = "toolStripMenuItem_Insert";
|
||||
toolStripMenuItem_Insert.Size = new Size(328, 30);
|
||||
toolStripMenuItem_Insert.Text = "插入...";
|
||||
toolStripMenuItem_Insert.Click += toolStripMenuItem_Insert_Click;
|
||||
//
|
||||
// toolStripMenuItem_Remove
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Remove, "toolStripMenuItem_Remove");
|
||||
toolStripMenuItem_Remove.Name = "toolStripMenuItem_Remove";
|
||||
toolStripMenuItem_Remove.ShortcutKeys = Keys.Delete;
|
||||
toolStripMenuItem_Remove.Size = new Size(328, 30);
|
||||
toolStripMenuItem_Remove.Text = "移除";
|
||||
toolStripMenuItem_Remove.Click += toolStripMenuItem_Remove_Click;
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1");
|
||||
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
toolStripSeparator1.Size = new Size(325, 6);
|
||||
//
|
||||
// toolStripMenuItem_BatchAdd
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_BatchAdd, "toolStripMenuItem_BatchAdd");
|
||||
toolStripMenuItem_BatchAdd.Name = "toolStripMenuItem_BatchAdd";
|
||||
toolStripMenuItem_BatchAdd.Size = new Size(328, 30);
|
||||
toolStripMenuItem_BatchAdd.Text = "批量添加...";
|
||||
toolStripMenuItem_BatchAdd.Click += toolStripMenuItem_BatchAdd_Click;
|
||||
//
|
||||
// toolStripMenuItem_RemoveAll
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_RemoveAll, "toolStripMenuItem_RemoveAll");
|
||||
toolStripMenuItem_RemoveAll.Name = "toolStripMenuItem_RemoveAll";
|
||||
toolStripMenuItem_RemoveAll.Size = new Size(328, 30);
|
||||
toolStripMenuItem_RemoveAll.Text = "移除全部";
|
||||
toolStripMenuItem_RemoveAll.Click += toolStripMenuItem_RemoveAll_Click;
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2");
|
||||
toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
toolStripSeparator2.Size = new Size(325, 6);
|
||||
//
|
||||
// toolStripMenuItem_MoveUp
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_MoveUp, "toolStripMenuItem_MoveUp");
|
||||
toolStripMenuItem_MoveUp.Name = "toolStripMenuItem_MoveUp";
|
||||
toolStripMenuItem_MoveUp.ShortcutKeys = Keys.Alt | Keys.W;
|
||||
toolStripMenuItem_MoveUp.Size = new Size(328, 30);
|
||||
toolStripMenuItem_MoveUp.Text = "上移";
|
||||
toolStripMenuItem_MoveUp.Click += toolStripMenuItem_MoveUp_Click;
|
||||
//
|
||||
// toolStripMenuItem_MoveDown
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_MoveDown, "toolStripMenuItem_MoveDown");
|
||||
toolStripMenuItem_MoveDown.Name = "toolStripMenuItem_MoveDown";
|
||||
toolStripMenuItem_MoveDown.ShortcutKeys = Keys.Alt | Keys.S;
|
||||
toolStripMenuItem_MoveDown.Size = new Size(328, 30);
|
||||
toolStripMenuItem_MoveDown.Text = "下移";
|
||||
toolStripMenuItem_MoveDown.Click += toolStripMenuItem_MoveDown_Click;
|
||||
//
|
||||
// toolStripMenuItem_MoveTop
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_MoveTop, "toolStripMenuItem_MoveTop");
|
||||
toolStripMenuItem_MoveTop.Name = "toolStripMenuItem_MoveTop";
|
||||
toolStripMenuItem_MoveTop.ShortcutKeys = Keys.Alt | Keys.Shift | Keys.W;
|
||||
toolStripMenuItem_MoveTop.Size = new Size(328, 30);
|
||||
toolStripMenuItem_MoveTop.Text = "置顶";
|
||||
toolStripMenuItem_MoveTop.Click += toolStripMenuItem_MoveTop_Click;
|
||||
//
|
||||
// toolStripMenuItem_MoveBottom
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_MoveBottom, "toolStripMenuItem_MoveBottom");
|
||||
toolStripMenuItem_MoveBottom.Name = "toolStripMenuItem_MoveBottom";
|
||||
toolStripMenuItem_MoveBottom.ShortcutKeys = Keys.Alt | Keys.Shift | Keys.S;
|
||||
toolStripMenuItem_MoveBottom.Size = new Size(328, 30);
|
||||
toolStripMenuItem_MoveBottom.Text = "置底";
|
||||
toolStripMenuItem_MoveBottom.Click += toolStripMenuItem_MoveBottom_Click;
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3");
|
||||
toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
toolStripSeparator3.Size = new Size(325, 6);
|
||||
//
|
||||
// toolStripMenuItem_SelectAll
|
||||
//
|
||||
toolStripMenuItem_SelectAll.Name = "toolStripMenuItem_SelectAll";
|
||||
toolStripMenuItem_SelectAll.ShortcutKeys = Keys.Control | Keys.A;
|
||||
toolStripMenuItem_SelectAll.Size = new Size(328, 30);
|
||||
toolStripMenuItem_SelectAll.Text = "全选";
|
||||
toolStripMenuItem_SelectAll.Click += toolStripMenuItem_SelectAll_Click;
|
||||
//
|
||||
// toolStripMenuItem_CopyPreview
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_CopyPreview, "toolStripMenuItem_CopyPreview");
|
||||
toolStripMenuItem_CopyPreview.Name = "toolStripMenuItem_CopyPreview";
|
||||
toolStripMenuItem_CopyPreview.ShortcutKeys = Keys.Control | Keys.C;
|
||||
toolStripMenuItem_CopyPreview.Size = new Size(328, 30);
|
||||
toolStripMenuItem_CopyPreview.Text = "复制预览图 (256x256)";
|
||||
toolStripMenuItem_CopyPreview.Click += toolStripMenuItem_CopyPreview_Click;
|
||||
//
|
||||
// toolStripMenuItem_AddFromClipboard
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_AddFromClipboard, "toolStripMenuItem_AddFromClipboard");
|
||||
toolStripMenuItem_AddFromClipboard.Name = "toolStripMenuItem_AddFromClipboard";
|
||||
toolStripMenuItem_AddFromClipboard.Click += toolStripMenuItem_AddFromClipboard_Click;
|
||||
//
|
||||
// toolStripMenuItem_SelectAll
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_SelectAll, "toolStripMenuItem_SelectAll");
|
||||
toolStripMenuItem_SelectAll.Name = "toolStripMenuItem_SelectAll";
|
||||
toolStripMenuItem_SelectAll.Click += toolStripMenuItem_SelectAll_Click;
|
||||
//
|
||||
// toolStripSeparator4
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator4, "toolStripSeparator4");
|
||||
toolStripSeparator4.Name = "toolStripSeparator4";
|
||||
toolStripSeparator4.Size = new Size(325, 6);
|
||||
//
|
||||
// toolStripMenuItem_ChangeView
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ChangeView, "toolStripMenuItem_ChangeView");
|
||||
toolStripMenuItem_ChangeView.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_LargeIconView, toolStripMenuItem_ListView, toolStripMenuItem_DetailsView });
|
||||
toolStripMenuItem_ChangeView.Name = "toolStripMenuItem_ChangeView";
|
||||
toolStripMenuItem_ChangeView.Size = new Size(328, 30);
|
||||
toolStripMenuItem_ChangeView.Text = "切换视图";
|
||||
//
|
||||
// toolStripMenuItem_LargeIconView
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_LargeIconView, "toolStripMenuItem_LargeIconView");
|
||||
toolStripMenuItem_LargeIconView.Name = "toolStripMenuItem_LargeIconView";
|
||||
toolStripMenuItem_LargeIconView.ShortcutKeys = Keys.Alt | Keys.D1;
|
||||
toolStripMenuItem_LargeIconView.Size = new Size(241, 34);
|
||||
toolStripMenuItem_LargeIconView.Text = "大图标";
|
||||
toolStripMenuItem_LargeIconView.Click += toolStripMenuItem_LargeIconView_Click;
|
||||
//
|
||||
// toolStripMenuItem_ListView
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ListView, "toolStripMenuItem_ListView");
|
||||
toolStripMenuItem_ListView.Name = "toolStripMenuItem_ListView";
|
||||
toolStripMenuItem_ListView.ShortcutKeys = Keys.Alt | Keys.D2;
|
||||
toolStripMenuItem_ListView.Size = new Size(241, 34);
|
||||
toolStripMenuItem_ListView.Text = "列表";
|
||||
toolStripMenuItem_ListView.Click += toolStripMenuItem_ListView_Click;
|
||||
//
|
||||
// toolStripMenuItem_DetailsView
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_DetailsView, "toolStripMenuItem_DetailsView");
|
||||
toolStripMenuItem_DetailsView.Name = "toolStripMenuItem_DetailsView";
|
||||
toolStripMenuItem_DetailsView.ShortcutKeys = Keys.Alt | Keys.D3;
|
||||
toolStripMenuItem_DetailsView.Size = new Size(241, 34);
|
||||
toolStripMenuItem_DetailsView.Text = "详细信息";
|
||||
toolStripMenuItem_DetailsView.Click += toolStripMenuItem_DetailsView_Click;
|
||||
//
|
||||
// imageList_LargeIcon
|
||||
//
|
||||
imageList_LargeIcon.ColorDepth = ColorDepth.Depth32Bit;
|
||||
imageList_LargeIcon.ImageSize = new Size(96, 96);
|
||||
resources.ApplyResources(imageList_LargeIcon, "imageList_LargeIcon");
|
||||
imageList_LargeIcon.TransparentColor = Color.Transparent;
|
||||
//
|
||||
// imageList_SmallIcon
|
||||
//
|
||||
imageList_SmallIcon.ColorDepth = ColorDepth.Depth32Bit;
|
||||
imageList_SmallIcon.ImageSize = new Size(48, 48);
|
||||
resources.ApplyResources(imageList_SmallIcon, "imageList_SmallIcon");
|
||||
imageList_SmallIcon.TransparentColor = Color.Transparent;
|
||||
//
|
||||
// toolStripMenuItem_AddFromClipboard
|
||||
// timer_SelectedIndexChangedDebounce
|
||||
//
|
||||
toolStripMenuItem_AddFromClipboard.Name = "toolStripMenuItem_AddFromClipboard";
|
||||
toolStripMenuItem_AddFromClipboard.ShortcutKeys = Keys.Control | Keys.V;
|
||||
toolStripMenuItem_AddFromClipboard.Size = new Size(328, 30);
|
||||
toolStripMenuItem_AddFromClipboard.Text = "从剪贴板添加";
|
||||
toolStripMenuItem_AddFromClipboard.Click += toolStripMenuItem_AddFromClipboard_Click;
|
||||
timer_SelectedIndexChangedDebounce.Interval = 30;
|
||||
timer_SelectedIndexChangedDebounce.Tick += timer_SelectedIndexChangedDebounce_Tick;
|
||||
//
|
||||
// statusStrip
|
||||
//
|
||||
resources.ApplyResources(statusStrip, "statusStrip");
|
||||
statusStrip.ImageScalingSize = new Size(24, 24);
|
||||
statusStrip.Items.AddRange(new ToolStripItem[] { toolStripStatusLabel_CountInfo });
|
||||
statusStrip.Name = "statusStrip";
|
||||
statusStrip.SizingGrip = false;
|
||||
//
|
||||
// toolStripStatusLabel_CountInfo
|
||||
//
|
||||
resources.ApplyResources(toolStripStatusLabel_CountInfo, "toolStripStatusLabel_CountInfo");
|
||||
toolStripStatusLabel_CountInfo.Name = "toolStripStatusLabel_CountInfo";
|
||||
//
|
||||
// tableLayoutPanel
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel, "tableLayoutPanel");
|
||||
tableLayoutPanel.Controls.Add(listView, 0, 0);
|
||||
tableLayoutPanel.Controls.Add(statusStrip, 0, 1);
|
||||
tableLayoutPanel.Name = "tableLayoutPanel";
|
||||
//
|
||||
// SpineListView
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(listView);
|
||||
Controls.Add(tableLayoutPanel);
|
||||
Name = "SpineListView";
|
||||
Size = new Size(336, 445);
|
||||
contextMenuStrip.ResumeLayout(false);
|
||||
statusStrip.ResumeLayout(false);
|
||||
statusStrip.PerformLayout();
|
||||
tableLayoutPanel.ResumeLayout(false);
|
||||
tableLayoutPanel.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
@@ -287,5 +290,9 @@
|
||||
private ToolStripMenuItem toolStripMenuItem_SelectAll;
|
||||
private ToolStripSeparator toolStripSeparator4;
|
||||
private ToolStripMenuItem toolStripMenuItem_AddFromClipboard;
|
||||
private System.Windows.Forms.Timer timer_SelectedIndexChangedDebounce;
|
||||
private StatusStrip statusStrip;
|
||||
private ToolStripStatusLabel toolStripStatusLabel_CountInfo;
|
||||
private TableLayoutPanel tableLayoutPanel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,26 +12,35 @@ using SpineViewer.Spine;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Specialized;
|
||||
using NLog;
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Utils;
|
||||
using SpineViewer.Spine.SpineView;
|
||||
using SpineViewer.Utils.Localize;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
public partial class SpineListView : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// 显示骨骼信息的属性面板
|
||||
/// 日志器
|
||||
/// </summary>
|
||||
[Category("自定义"), Description("用于显示骨骼属性的属性页")]
|
||||
public PropertyGrid? PropertyGrid { get; set; }
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Spine 列表只读视图, 访问时必须使用 lock 语句锁定视图本身
|
||||
/// </summary>
|
||||
public readonly ReadOnlyCollection<Spine.Spine> Spines;
|
||||
public readonly ReadOnlyCollection<SpineObject> Spines;
|
||||
|
||||
/// <summary>
|
||||
/// Spine 列表, 访问时必须使用 lock 语句锁定只读视图 Spines
|
||||
/// </summary>
|
||||
private readonly List<Spine.Spine> spines = [];
|
||||
private readonly List<SpineObject> spines = [];
|
||||
|
||||
/// <summary>
|
||||
/// 用于属性页显示模型参数的包装类
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, SpineObjectProperty> spinePropertyWrappers = [];
|
||||
|
||||
public SpineListView()
|
||||
{
|
||||
@@ -39,6 +48,13 @@ namespace SpineViewer.Controls
|
||||
Spines = spines.AsReadOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示骨骼信息的属性面板
|
||||
/// </summary>
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDescription(typeof(Properties.Resources), "descModelAttributes")]
|
||||
public SpineViewPropertyGrid? SpinePropertyGrid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 选中的索引
|
||||
/// </summary>
|
||||
@@ -55,8 +71,7 @@ namespace SpineViewer.Controls
|
||||
private void Insert(int index = -1)
|
||||
{
|
||||
var dialog = new Dialogs.OpenSpineDialog();
|
||||
if (dialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
if (dialog.ShowDialog() != DialogResult.OK) return;
|
||||
Insert(dialog.Result, index);
|
||||
}
|
||||
|
||||
@@ -67,19 +82,17 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
try
|
||||
{
|
||||
var spine = Spine.Spine.New(result.Version, result.SkelPath, result.AtlasPath);
|
||||
var spine = SpineObject.New(result.Version, result.SkelPath, result.AtlasPath);
|
||||
|
||||
// 如果索引无效则在末尾添加
|
||||
if (index < 0 || index > listView.Items.Count)
|
||||
index = listView.Items.Count;
|
||||
|
||||
// 锁定外部的读操作
|
||||
lock (Spines)
|
||||
{
|
||||
spines.Insert(index, spine);
|
||||
listView.SmallImageList.Images.Add(spine.ID, spine.Preview);
|
||||
listView.LargeImageList.Images.Add(spine.ID, spine.Preview);
|
||||
}
|
||||
lock (Spines) { spines.Insert(index, spine); }
|
||||
spinePropertyWrappers[spine.ID] = new(spine);
|
||||
listView.SmallImageList.Images.Add(spine.ID, spine.Preview);
|
||||
listView.LargeImageList.Images.Add(spine.ID, spine.Preview);
|
||||
listView.Items.Insert(index, new ListViewItem(spine.Name, spine.ID) { ToolTipText = spine.SkelPath });
|
||||
|
||||
// 选中新增项
|
||||
@@ -88,12 +101,12 @@ namespace SpineViewer.Controls
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Logger.Error(ex.ToString());
|
||||
Program.Logger.Error("Failed to load {} {}", result.SkelPath, result.AtlasPath);
|
||||
MessageBox.Error(ex.ToString(), "骨骼加载失败");
|
||||
logger.Error(ex.ToString());
|
||||
logger.Error("Failed to load {} {}", result.SkelPath, result.AtlasPath);
|
||||
MessagePopup.Error(ex.ToString(), Properties.Resources.errorLoadSkeleton);
|
||||
}
|
||||
|
||||
Program.LogCurrentMemoryUsage();
|
||||
logger.LogCurrentProcessMemoryUsage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -102,15 +115,14 @@ namespace SpineViewer.Controls
|
||||
public void BatchAdd()
|
||||
{
|
||||
var openDialog = new Dialogs.BatchOpenSpineDialog();
|
||||
if (openDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
if (openDialog.ShowDialog() != DialogResult.OK) return;
|
||||
BatchAdd(openDialog.Result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从结果批量添加
|
||||
/// </summary>
|
||||
public void BatchAdd(Dialogs.BatchOpenSpineDialogResult result)
|
||||
private void BatchAdd(Dialogs.BatchOpenSpineDialogResult result)
|
||||
{
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += BatchAdd_Work;
|
||||
@@ -132,7 +144,7 @@ namespace SpineViewer.Controls
|
||||
int success = 0;
|
||||
int error = 0;
|
||||
|
||||
worker.ReportProgress(0, $"已处理 0/{totalCount}");
|
||||
worker.ReportProgress(0, $"{Properties.Resources.process} 0/{totalCount}");
|
||||
for (int i = 0; i < totalCount; i++)
|
||||
{
|
||||
if (worker.CancellationPending)
|
||||
@@ -145,9 +157,10 @@ namespace SpineViewer.Controls
|
||||
|
||||
try
|
||||
{
|
||||
var spine = Spine.Spine.New(version, skelPath);
|
||||
var spine = SpineObject.New(version, skelPath);
|
||||
var preview = spine.Preview;
|
||||
lock (Spines) { spines.Add(spine); }
|
||||
spinePropertyWrappers[spine.ID] = new(spine);
|
||||
listView.Invoke(() =>
|
||||
{
|
||||
listView.SmallImageList.Images.Add(spine.ID, preview);
|
||||
@@ -158,24 +171,30 @@ namespace SpineViewer.Controls
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Logger.Error(ex.ToString());
|
||||
Program.Logger.Error("Failed to load {}", skelPath);
|
||||
logger.Error(ex.ToString());
|
||||
logger.Error("Failed to load {}", skelPath);
|
||||
error++;
|
||||
}
|
||||
|
||||
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"已处理 {i + 1}/{totalCount}");
|
||||
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"{Properties.Resources.process} {i + 1}/{totalCount}");
|
||||
}
|
||||
|
||||
// 选中最后一项
|
||||
listView.Invoke(() =>
|
||||
{
|
||||
if (listView.Items.Count > 0)
|
||||
{
|
||||
listView.SelectedIndices.Clear();
|
||||
listView.SelectedIndices.Add(listView.Items.Count - 1);
|
||||
}
|
||||
});
|
||||
|
||||
if (error > 0)
|
||||
{
|
||||
Program.Logger.Warn("Batch load {} successfully, {} failed", success, error);
|
||||
}
|
||||
logger.Warn("Batch load {} successfully, {} failed", success, error);
|
||||
else
|
||||
{
|
||||
Program.Logger.Info("{} skel loaded successfully", success);
|
||||
}
|
||||
logger.Info("{} skel loaded successfully", success);
|
||||
|
||||
Program.LogCurrentMemoryUsage();
|
||||
logger.LogCurrentProcessMemoryUsage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -188,14 +207,14 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower()))
|
||||
if (SpineUtils.CommonSkelSuffix.Contains(Path.GetExtension(path).ToLower()))
|
||||
validPaths.Add(path);
|
||||
}
|
||||
else if (Directory.Exists(path))
|
||||
{
|
||||
foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (Spine.Spine.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
if (SpineUtils.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
validPaths.Add(file);
|
||||
}
|
||||
}
|
||||
@@ -205,29 +224,41 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
if (validPaths.Count > 100)
|
||||
{
|
||||
if (MessageBox.Quest($"共发现 {validPaths.Count} 个可加载骨骼,数量较多,是否一次性全部加载?") == DialogResult.Cancel)
|
||||
if (MessagePopup.Quest($"{Properties.Resources.loadAllSkeletonPrefix}{validPaths.Count}{Properties.Resources.loadAllSkeletonSuffix}", Properties.Resources.msgBoxQuest) == DialogResult.Cancel)
|
||||
return;
|
||||
}
|
||||
BatchAdd(new Dialogs.BatchOpenSpineDialogResult(Spine.Version.Auto, validPaths.ToArray()));
|
||||
BatchAdd(new Dialogs.BatchOpenSpineDialogResult(SpineVersion.Auto, validPaths.ToArray()));
|
||||
}
|
||||
else if (validPaths.Count > 0)
|
||||
{
|
||||
Insert(new Dialogs.OpenSpineDialogResult(Spine.Version.Auto, validPaths[0]));
|
||||
Insert(new Dialogs.OpenSpineDialogResult(SpineVersion.Auto, validPaths[0]));
|
||||
}
|
||||
}
|
||||
|
||||
private void listView_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
timer_SelectedIndexChangedDebounce.Stop();
|
||||
timer_SelectedIndexChangedDebounce.Start();
|
||||
}
|
||||
|
||||
private void timer_SelectedIndexChangedDebounce_Tick(object sender, EventArgs e)
|
||||
{
|
||||
timer_SelectedIndexChangedDebounce.Stop();
|
||||
_listView_SelectedIndexChanged(listView, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void _listView_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
lock (Spines)
|
||||
{
|
||||
if (PropertyGrid is not null)
|
||||
if (SpinePropertyGrid is not null)
|
||||
{
|
||||
if (listView.SelectedIndices.Count <= 0)
|
||||
PropertyGrid.SelectedObject = null;
|
||||
SpinePropertyGrid.SelectedSpines = null;
|
||||
else if (listView.SelectedIndices.Count <= 1)
|
||||
PropertyGrid.SelectedObject = spines[listView.SelectedIndices[0]];
|
||||
SpinePropertyGrid.SelectedSpines = [spinePropertyWrappers[spines[listView.SelectedIndices[0]].ID]];
|
||||
else
|
||||
PropertyGrid.SelectedObjects = listView.SelectedIndices.Cast<int>().Select(index => spines[index]).ToArray();
|
||||
SpinePropertyGrid.SelectedSpines = listView.SelectedIndices.Cast<int>().Select(index => spinePropertyWrappers[spines[index].ID]).ToArray();
|
||||
}
|
||||
|
||||
// 标记选中的 Spine
|
||||
@@ -246,6 +277,8 @@ namespace SpineViewer.Controls
|
||||
|
||||
if (listView.SelectedItems.Count > 0)
|
||||
listView.SelectedItems[0].EnsureVisible();
|
||||
|
||||
toolStripStatusLabel_CountInfo.Text = $"{Properties.Resources.countInfoStatusPrefix} {listView.SelectedItems.Count} {Properties.Resources.countInfoStatusMidfix} {listView.Items.Count} {Properties.Resources.countInfoStatusSuffix}";
|
||||
}
|
||||
|
||||
private void listView_ItemDrag(object sender, ItemDragEventArgs e)
|
||||
@@ -341,6 +374,7 @@ namespace SpineViewer.Controls
|
||||
toolStripMenuItem_MoveDown.Enabled = selectedCount == 1 && selectedIndices[0] != itemsCount - 1;
|
||||
toolStripMenuItem_MoveBottom.Enabled = selectedCount == 1 && selectedIndices[0] != itemsCount - 1;
|
||||
toolStripMenuItem_RemoveAll.Enabled = itemsCount > 0;
|
||||
toolStripMenuItem_CopyPreview.Enabled = selectedCount > 0;
|
||||
|
||||
// 视图选项
|
||||
toolStripMenuItem_LargeIconView.Checked = listView.View == View.LargeIcon;
|
||||
@@ -379,21 +413,24 @@ namespace SpineViewer.Controls
|
||||
|
||||
if (listView.SelectedIndices.Count > 1)
|
||||
{
|
||||
if (MessageBox.Quest($"确定移除所选 {listView.SelectedIndices.Count} 项吗?") != DialogResult.OK)
|
||||
if (MessagePopup.Quest($"{Properties.Resources.removeItemConfirmPrefix} {listView.SelectedIndices.Count} {Properties.Resources.removeItemConfirmSuffix}", Properties.Resources.msgBoxQuest) != DialogResult.OK)
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var i in listView.SelectedIndices.Cast<int>().OrderByDescending(x => x))
|
||||
lock (Spines)
|
||||
{
|
||||
listView.Items.RemoveAt(i);
|
||||
lock (Spines)
|
||||
listView.BeginUpdate();
|
||||
foreach (var i in listView.SelectedIndices.Cast<int>().OrderByDescending(x => x))
|
||||
{
|
||||
listView.Items.RemoveAt(i);
|
||||
var spine = spines[i];
|
||||
spines.RemoveAt(i);
|
||||
spinePropertyWrappers.Remove(spine.ID);
|
||||
listView.SmallImageList.Images.RemoveByKey(spine.ID);
|
||||
listView.LargeImageList.Images.RemoveByKey(spine.ID);
|
||||
spine.Dispose();
|
||||
}
|
||||
listView.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,7 +513,7 @@ namespace SpineViewer.Controls
|
||||
if (listView.Items.Count <= 0)
|
||||
return;
|
||||
|
||||
if (MessageBox.Quest($"确认移除所有 {listView.Items.Count} 项吗?") != DialogResult.OK)
|
||||
if (MessagePopup.Quest($"{Properties.Resources.removeAllItemPrefix} {listView.Items.Count} {Properties.Resources.removeItemConfirmSuffix}", Properties.Resources.msgBoxQuest) != DialogResult.OK)
|
||||
return;
|
||||
|
||||
listView.Items.Clear();
|
||||
@@ -484,26 +521,28 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
foreach (var spine in spines) spine.Dispose();
|
||||
spines.Clear();
|
||||
spinePropertyWrappers.Clear();
|
||||
listView.SmallImageList.Images.Clear();
|
||||
listView.LargeImageList.Images.Clear();
|
||||
}
|
||||
if (PropertyGrid is not null)
|
||||
PropertyGrid.SelectedObject = null;
|
||||
if (SpinePropertyGrid is not null)
|
||||
SpinePropertyGrid.SelectedSpines = null;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_CopyPreview_Click(object sender, EventArgs e)
|
||||
{
|
||||
var fileDropList = new StringCollection();
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), Process.GetCurrentProcess().ProcessName);
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
lock (Spines)
|
||||
{
|
||||
foreach (int i in listView.SelectedIndices)
|
||||
{
|
||||
var a = Process.GetCurrentProcess();
|
||||
var spine = spines[i];
|
||||
var image = spine.Preview;
|
||||
var path = Path.Combine(Program.TempDir, $"{spine.ID}.png");
|
||||
using (var clone = new Bitmap(image))
|
||||
clone.Save(path);
|
||||
var path = Path.Combine(tempDir, $"{spine.ID}.png");
|
||||
spine.Preview.Save(path);
|
||||
fileDropList.Add(path);
|
||||
}
|
||||
}
|
||||
@@ -545,4 +584,9 @@ namespace SpineViewer.Controls
|
||||
listView.View = View.Details;
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultSpineConfig
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
241
SpineViewer/Controls/SpineListView.en.resx
Normal file
241
SpineViewer/Controls/SpineListView.en.resx
Normal file
@@ -0,0 +1,241 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="columnHeader_Name.Text" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>298, 418</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Add.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Add.Text" xml:space="preserve">
|
||||
<value>Add to...</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Insert.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Insert.Text" xml:space="preserve">
|
||||
<value>Insert...</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
|
||||
<value>Remove</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>294, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchAdd.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchAdd.Text" xml:space="preserve">
|
||||
<value>Bulk add...</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAll.Text" xml:space="preserve">
|
||||
<value>Remove all</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>294, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.Text" xml:space="preserve">
|
||||
<value>Up</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.Text" xml:space="preserve">
|
||||
<value>Down</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.Text" xml:space="preserve">
|
||||
<value>Stick to top</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.Text" xml:space="preserve">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>294, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.Text" xml:space="preserve">
|
||||
<value>Copy preview</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddFromClipboard.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddFromClipboard.Text" xml:space="preserve">
|
||||
<value>Add to clipboard</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Text" xml:space="preserve">
|
||||
<value>Select all</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>294, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ChangeView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ChangeView.Text" xml:space="preserve">
|
||||
<value>Switch view</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>258, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.Text" xml:space="preserve">
|
||||
<value>Large icon</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ListView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>258, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ListView.Text" xml:space="preserve">
|
||||
<value>List</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>258, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.Text" xml:space="preserve">
|
||||
<value>Details</value>
|
||||
</data>
|
||||
<data name="toolStripStatusLabel_CountInfo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>266, 24</value>
|
||||
</data>
|
||||
<data name="toolStripStatusLabel_CountInfo.Text" xml:space="preserve">
|
||||
<value>0 items selected, 0 items total</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,12 +117,451 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name=">>imageList_LargeIcon.Name" xml:space="preserve">
|
||||
<value>imageList_LargeIcon</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="toolStripMenuItem_AddFromClipboard.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveDown.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>imageList_SmallIcon.Name" xml:space="preserve">
|
||||
<value>imageList_SmallIcon</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>251, 6</value>
|
||||
</data>
|
||||
<data name="toolStripStatusLabel_CountInfo.Text" xml:space="preserve">
|
||||
<value>已选择 0 项,共 0 项</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Insert.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Insert</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Add.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_DetailsView.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_DetailsView</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>241, 34</value>
|
||||
</data>
|
||||
<data name=">>imageList_SmallIcon.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>251, 6</value>
|
||||
</data>
|
||||
<data name="statusStrip.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 414</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_AddFromClipboard.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>336, 445</value>
|
||||
</data>
|
||||
<data name="statusStrip.Text" xml:space="preserve">
|
||||
<value>statusStrip1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="columnHeader_Name.Text" xml:space="preserve">
|
||||
<value>名称</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator2.Name" xml:space="preserve">
|
||||
<value>toolStripSeparator2</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveTop.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.Text" xml:space="preserve">
|
||||
<value>置底</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_BatchAdd.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_BatchAdd</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name=">>columnHeader_Name.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAll.Text" xml:space="preserve">
|
||||
<value>移除全部</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Add.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>listView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ListView, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>statusStrip.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Remove.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Remove</value>
|
||||
</data>
|
||||
<data name=">>statusStrip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.StatusStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Remove.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>251, 6</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>SpineListView</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveUp.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="toolStripMenuItem_ListView.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+2</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_LargeIconView.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_LargeIconView</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="listView" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="statusStrip" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>timer_SelectedIndexChangedDebounce.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Timer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>listView.Name" xml:space="preserve">
|
||||
<value>listView</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.Text" xml:space="preserve">
|
||||
<value>上移</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Insert.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.Text" xml:space="preserve">
|
||||
<value>详细信息</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveTop.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_MoveTop</value>
|
||||
</data>
|
||||
<data name="statusStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>336, 31</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>251, 6</value>
|
||||
</data>
|
||||
<data name=">>statusStrip.Name" xml:space="preserve">
|
||||
<value>statusStrip</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+Shift+S</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator4.Name" xml:space="preserve">
|
||||
<value>toolStripSeparator4</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddFromClipboard.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+V</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveBottom.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchAdd.Text" xml:space="preserve">
|
||||
<value>批量添加...</value>
|
||||
</data>
|
||||
<data name=">>imageList_LargeIcon.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ChangeView.Text" xml:space="preserve">
|
||||
<value>切换视图</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ListView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>listView.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveBottom.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_MoveBottom</value>
|
||||
</data>
|
||||
<data name="listView.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_AddFromClipboard.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_AddFromClipboard</value>
|
||||
</data>
|
||||
<data name="columnHeader_Name.Width" type="System.Int32, mscorlib">
|
||||
<value>300</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator1.Name" xml:space="preserve">
|
||||
<value>toolStripSeparator1</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
|
||||
<value>移除</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_BatchAdd.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_RemoveAll.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_RemoveAll</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.Text" xml:space="preserve">
|
||||
<value>置顶</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_DetailsView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ListView.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_ListView</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ListView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>241, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+S</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripStatusLabel_CountInfo.Name" xml:space="preserve">
|
||||
<value>toolStripStatusLabel_CountInfo</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>listView.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>statusStrip.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel</value>
|
||||
</data>
|
||||
<data name="listView.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_CopyPreview.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveUp.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_MoveUp</value>
|
||||
</data>
|
||||
<data name="listView.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Insert.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Del</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+W</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ChangeView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>timer_SelectedIndexChangedDebounce.Name" xml:space="preserve">
|
||||
<value>timer_SelectedIndexChangedDebounce</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+C</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_SelectAll.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_SelectAll</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator3.Name" xml:space="preserve">
|
||||
<value>toolStripSeparator3</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Add.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Add</value>
|
||||
</data>
|
||||
<data name="listView.Alignment" type="System.Windows.Forms.ListViewAlignment, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ListView.Text" xml:space="preserve">
|
||||
<value>列表</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddFromClipboard.Text" xml:space="preserve">
|
||||
<value>从剪贴板添加</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.Text" xml:space="preserve">
|
||||
<value>大图标</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.RowCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+3</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Text" xml:space="preserve">
|
||||
<value>全选</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchAdd.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>255, 418</value>
|
||||
</data>
|
||||
<data name="statusStrip.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_LargeIconView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripStatusLabel_CountInfo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>178, 24</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.Text" xml:space="preserve">
|
||||
<value>下移</value>
|
||||
</data>
|
||||
<data name="imageList_SmallIcon.ImageSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>48, 48</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ChangeView.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_ChangeView</value>
|
||||
</data>
|
||||
<data name=">>columnHeader_Name.Name" xml:space="preserve">
|
||||
<value>columnHeader_Name</value>
|
||||
</data>
|
||||
<data name="listView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>336, 414</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_CopyPreview.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_CopyPreview</value>
|
||||
</data>
|
||||
<data name="imageList_LargeIcon.ImageSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>96, 96</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_RemoveAll.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="listView.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip.Name" xml:space="preserve">
|
||||
<value>contextMenuStrip</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveDown.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_MoveDown</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+A</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator4.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="statusStrip.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>241, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.Text" xml:space="preserve">
|
||||
<value>复制预览图</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>11, 24</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+Shift+W</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Insert.Text" xml:space="preserve">
|
||||
<value>插入...</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ChangeView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_SelectAll.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripStatusLabel_CountInfo.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Add.Text" xml:space="preserve">
|
||||
<value>添加...</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>336, 445</value>
|
||||
</data>
|
||||
<metadata name="timer_SelectedIndexChangedDebounce.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>771, 24</value>
|
||||
</metadata>
|
||||
<metadata name="statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>1176, 24</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
<value>30, 22</value>
|
||||
</metadata>
|
||||
<metadata name="imageList_LargeIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>511, 20</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="imageList_SmallIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>252, 19</value>
|
||||
</metadata>
|
||||
|
||||
231
SpineViewer/Controls/SpinePreviewPanel.Designer.cs
generated
Normal file
231
SpineViewer/Controls/SpinePreviewPanel.Designer.cs
generated
Normal file
@@ -0,0 +1,231 @@
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
partial class SpinePreviewPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 组件设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpinePreviewPanel));
|
||||
panel_Render = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
flowLayoutPanel1 = new FlowLayoutPanel();
|
||||
button_Stop = new Button();
|
||||
imageList = new ImageList(components);
|
||||
button_Restart = new Button();
|
||||
button_Start = new Button();
|
||||
button_ForwardStep = new Button();
|
||||
button_ForwardFast = new Button();
|
||||
button_FullScreen = new Button();
|
||||
panel_ViewContainer = new Panel();
|
||||
panel_RenderContainer = new Panel();
|
||||
toolTip = new ToolTip(components);
|
||||
spinePreviewFullScreenForm = new SpineViewer.Forms.SpinePreviewFullScreenForm();
|
||||
wallpaperForm = new WallpaperForm();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
flowLayoutPanel1.SuspendLayout();
|
||||
panel_ViewContainer.SuspendLayout();
|
||||
panel_RenderContainer.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel_Render
|
||||
//
|
||||
resources.ApplyResources(panel_Render, "panel_Render");
|
||||
panel_Render.BackColor = SystemColors.ControlDarkDark;
|
||||
panel_Render.Name = "panel_Render";
|
||||
toolTip.SetToolTip(panel_Render, resources.GetString("panel_Render.ToolTip"));
|
||||
panel_Render.MouseDown += panel_Render_MouseDown;
|
||||
panel_Render.MouseMove += panel_Render_MouseMove;
|
||||
panel_Render.MouseUp += panel_Render_MouseUp;
|
||||
panel_Render.MouseWheel += panel_Render_MouseWheel;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(flowLayoutPanel1, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(panel_ViewContainer, 0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
toolTip.SetToolTip(tableLayoutPanel1, resources.GetString("tableLayoutPanel1.ToolTip"));
|
||||
//
|
||||
// flowLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1");
|
||||
flowLayoutPanel1.Controls.Add(button_Stop);
|
||||
flowLayoutPanel1.Controls.Add(button_Restart);
|
||||
flowLayoutPanel1.Controls.Add(button_Start);
|
||||
flowLayoutPanel1.Controls.Add(button_ForwardStep);
|
||||
flowLayoutPanel1.Controls.Add(button_ForwardFast);
|
||||
flowLayoutPanel1.Controls.Add(button_FullScreen);
|
||||
flowLayoutPanel1.Name = "flowLayoutPanel1";
|
||||
toolTip.SetToolTip(flowLayoutPanel1, resources.GetString("flowLayoutPanel1.ToolTip"));
|
||||
//
|
||||
// button_Stop
|
||||
//
|
||||
resources.ApplyResources(button_Stop, "button_Stop");
|
||||
button_Stop.ImageList = imageList;
|
||||
button_Stop.Name = "button_Stop";
|
||||
toolTip.SetToolTip(button_Stop, resources.GetString("button_Stop.ToolTip"));
|
||||
button_Stop.UseVisualStyleBackColor = true;
|
||||
button_Stop.Click += button_Stop_Click;
|
||||
//
|
||||
// imageList
|
||||
//
|
||||
imageList.ColorDepth = ColorDepth.Depth32Bit;
|
||||
imageList.ImageStream = (ImageListStreamer)resources.GetObject("imageList.ImageStream");
|
||||
imageList.TransparentColor = Color.Transparent;
|
||||
imageList.Images.SetKeyName(0, "arrows-maximize");
|
||||
imageList.Images.SetKeyName(1, "forward-fast");
|
||||
imageList.Images.SetKeyName(2, "forward-step");
|
||||
imageList.Images.SetKeyName(3, "pause");
|
||||
imageList.Images.SetKeyName(4, "rotate-left");
|
||||
imageList.Images.SetKeyName(5, "start");
|
||||
imageList.Images.SetKeyName(6, "stop");
|
||||
//
|
||||
// button_Restart
|
||||
//
|
||||
resources.ApplyResources(button_Restart, "button_Restart");
|
||||
button_Restart.ImageList = imageList;
|
||||
button_Restart.Name = "button_Restart";
|
||||
toolTip.SetToolTip(button_Restart, resources.GetString("button_Restart.ToolTip"));
|
||||
button_Restart.UseVisualStyleBackColor = true;
|
||||
button_Restart.Click += button_Restart_Click;
|
||||
//
|
||||
// button_Start
|
||||
//
|
||||
resources.ApplyResources(button_Start, "button_Start");
|
||||
button_Start.ImageList = imageList;
|
||||
button_Start.Name = "button_Start";
|
||||
toolTip.SetToolTip(button_Start, resources.GetString("button_Start.ToolTip"));
|
||||
button_Start.UseVisualStyleBackColor = true;
|
||||
button_Start.Click += button_Start_Click;
|
||||
//
|
||||
// button_ForwardStep
|
||||
//
|
||||
resources.ApplyResources(button_ForwardStep, "button_ForwardStep");
|
||||
button_ForwardStep.ImageList = imageList;
|
||||
button_ForwardStep.Name = "button_ForwardStep";
|
||||
toolTip.SetToolTip(button_ForwardStep, resources.GetString("button_ForwardStep.ToolTip"));
|
||||
button_ForwardStep.UseVisualStyleBackColor = true;
|
||||
button_ForwardStep.Click += button_ForwardStep_Click;
|
||||
//
|
||||
// button_ForwardFast
|
||||
//
|
||||
resources.ApplyResources(button_ForwardFast, "button_ForwardFast");
|
||||
button_ForwardFast.ImageList = imageList;
|
||||
button_ForwardFast.Name = "button_ForwardFast";
|
||||
toolTip.SetToolTip(button_ForwardFast, resources.GetString("button_ForwardFast.ToolTip"));
|
||||
button_ForwardFast.UseVisualStyleBackColor = true;
|
||||
button_ForwardFast.Click += button_ForwardFast_Click;
|
||||
//
|
||||
// button_FullScreen
|
||||
//
|
||||
resources.ApplyResources(button_FullScreen, "button_FullScreen");
|
||||
button_FullScreen.ImageList = imageList;
|
||||
button_FullScreen.Name = "button_FullScreen";
|
||||
toolTip.SetToolTip(button_FullScreen, resources.GetString("button_FullScreen.ToolTip"));
|
||||
button_FullScreen.UseVisualStyleBackColor = true;
|
||||
button_FullScreen.Click += button_FullScreen_Click;
|
||||
//
|
||||
// panel_ViewContainer
|
||||
//
|
||||
resources.ApplyResources(panel_ViewContainer, "panel_ViewContainer");
|
||||
panel_ViewContainer.Controls.Add(panel_RenderContainer);
|
||||
panel_ViewContainer.Name = "panel_ViewContainer";
|
||||
toolTip.SetToolTip(panel_ViewContainer, resources.GetString("panel_ViewContainer.ToolTip"));
|
||||
//
|
||||
// panel_RenderContainer
|
||||
//
|
||||
resources.ApplyResources(panel_RenderContainer, "panel_RenderContainer");
|
||||
panel_RenderContainer.BackColor = SystemColors.ControlDark;
|
||||
panel_RenderContainer.Controls.Add(panel_Render);
|
||||
panel_RenderContainer.Name = "panel_RenderContainer";
|
||||
toolTip.SetToolTip(panel_RenderContainer, resources.GetString("panel_RenderContainer.ToolTip"));
|
||||
panel_RenderContainer.SizeChanged += panel_RenderContainer_SizeChanged;
|
||||
//
|
||||
// spinePreviewFullScreenForm
|
||||
//
|
||||
resources.ApplyResources(spinePreviewFullScreenForm, "spinePreviewFullScreenForm");
|
||||
spinePreviewFullScreenForm.ControlBox = false;
|
||||
spinePreviewFullScreenForm.FormBorderStyle = FormBorderStyle.None;
|
||||
spinePreviewFullScreenForm.MaximizeBox = false;
|
||||
spinePreviewFullScreenForm.MinimizeBox = false;
|
||||
spinePreviewFullScreenForm.Name = "SpinePreviewFullScreenForm";
|
||||
spinePreviewFullScreenForm.ShowIcon = false;
|
||||
spinePreviewFullScreenForm.ShowInTaskbar = false;
|
||||
toolTip.SetToolTip(spinePreviewFullScreenForm, resources.GetString("spinePreviewFullScreenForm.ToolTip"));
|
||||
spinePreviewFullScreenForm.TopMost = true;
|
||||
spinePreviewFullScreenForm.FormClosing += spinePreviewFullScreenForm_FormClosing;
|
||||
spinePreviewFullScreenForm.KeyDown += spinePreviewFullScreenForm_KeyDown;
|
||||
//
|
||||
// wallpaperForm
|
||||
//
|
||||
resources.ApplyResources(wallpaperForm, "wallpaperForm");
|
||||
wallpaperForm.ControlBox = false;
|
||||
wallpaperForm.FormBorderStyle = FormBorderStyle.None;
|
||||
wallpaperForm.MaximizeBox = false;
|
||||
wallpaperForm.MinimizeBox = false;
|
||||
wallpaperForm.Name = "WallpaperForm";
|
||||
wallpaperForm.ShowIcon = false;
|
||||
wallpaperForm.ShowInTaskbar = false;
|
||||
toolTip.SetToolTip(wallpaperForm, resources.GetString("wallpaperForm.ToolTip"));
|
||||
wallpaperForm.WindowState = FormWindowState.Minimized;
|
||||
wallpaperForm.FormClosing += wallpaperForm_FormClosing;
|
||||
//
|
||||
// SpinePreviewPanel
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(tableLayoutPanel1);
|
||||
Name = "SpinePreviewPanel";
|
||||
toolTip.SetToolTip(this, resources.GetString("$this.ToolTip"));
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
flowLayoutPanel1.ResumeLayout(false);
|
||||
flowLayoutPanel1.PerformLayout();
|
||||
panel_ViewContainer.ResumeLayout(false);
|
||||
panel_RenderContainer.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel_Render;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Panel panel_RenderContainer;
|
||||
private FlowLayoutPanel flowLayoutPanel1;
|
||||
private Button button_Stop;
|
||||
private Button button_Start;
|
||||
private ImageList imageList;
|
||||
private ToolTip toolTip;
|
||||
private Button button_ForwardStep;
|
||||
private Button button_ForwardFast;
|
||||
private Button button_Restart;
|
||||
private Button button_FullScreen;
|
||||
private Panel panel_ViewContainer;
|
||||
private Forms.SpinePreviewFullScreenForm spinePreviewFullScreenForm;
|
||||
private WallpaperForm wallpaperForm;
|
||||
}
|
||||
}
|
||||
837
SpineViewer/Controls/SpinePreviewPanel.cs
Normal file
837
SpineViewer/Controls/SpinePreviewPanel.cs
Normal file
@@ -0,0 +1,837 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Security.Policy;
|
||||
using System.Diagnostics;
|
||||
using NLog;
|
||||
using SpineViewer.Utils;
|
||||
using System.Drawing.Design;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using SpineViewer.Utils.Localize;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
public partial class SpinePreviewPanel : UserControl
|
||||
{
|
||||
public SpinePreviewPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 日志器
|
||||
/// </summary>
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 要绑定的 Spine 列表控件
|
||||
/// </summary>
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDescription(typeof(Properties.Resources), "descAssociatedSpineListView")]
|
||||
public SpineListView? SpineListView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 属性信息面板
|
||||
/// </summary>
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDescription(typeof(Properties.Resources), "descDisplayImageProperties")]
|
||||
public PropertyGrid? PropertyGrid
|
||||
{
|
||||
get => propertyGrid;
|
||||
set
|
||||
{
|
||||
propertyGrid = value;
|
||||
if (propertyGrid is not null)
|
||||
propertyGrid.SelectedObject = new SpinePreviewPanelProperty(this);
|
||||
}
|
||||
}
|
||||
private PropertyGrid? propertyGrid;
|
||||
|
||||
#region 参数属性
|
||||
|
||||
/// <summary>
|
||||
/// 分辨率
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public Size Resolution
|
||||
{
|
||||
get => resolution;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
if (value == resolution) return;
|
||||
if (value.Width <= 0) value.Width = 100;
|
||||
if (value.Height <= 0) value.Height = 100;
|
||||
|
||||
var previousZoom = Zoom;
|
||||
|
||||
float parentW = panel_Render.Parent.Width;
|
||||
float parentH = panel_Render.Parent.Height;
|
||||
float renderW = value.Width;
|
||||
float renderH = value.Height;
|
||||
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
||||
renderW *= scale;
|
||||
renderH *= scale;
|
||||
|
||||
panel_Render.Location = new((int)((parentW - renderW) / 2 + 0.5), (int)((parentH - renderH) / 2 + 0.5));
|
||||
panel_Render.Size = new((int)(renderW + 0.5), (int)(renderH + 0.5));
|
||||
resolution = value;
|
||||
|
||||
// 设置完 resolution 后还原缩放比例
|
||||
Zoom = previousZoom;
|
||||
|
||||
// 设置壁纸窗口分辨率
|
||||
using var view = renderWindow.GetView();
|
||||
wallpaperWindow.SetView(view);
|
||||
wallpaperForm.Size = value; // 必须两个 Size 都设置
|
||||
wallpaperWindow.Size = new((uint)value.Width, (uint)value.Height);
|
||||
}
|
||||
}
|
||||
private Size resolution = new(100, 100);
|
||||
|
||||
/// <summary>
|
||||
/// 画面中心点
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public PointF Center
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return new(-1, -1);
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var center = view.Center;
|
||||
return new(center.X, center.Y);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
view.Center = new(value.X, value.Y);
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画面缩放
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public float Zoom
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return -1;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return resolution.Width / Math.Abs(view.Size.X);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
value = Math.Clamp(value, 0.001f, 1000f);
|
||||
using var view = renderWindow.GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
view.Size = new(resolution.Width / value * signX, resolution.Height / value * signY);
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画面旋转
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public float Rotation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return -1;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Rotation;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
view.Rotation = value;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 水平翻转
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool FlipX
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return false;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Size.X < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.X > 0 && value || size.X < 0 && !value)
|
||||
size.X *= -1;
|
||||
view.Size = size;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 垂直翻转
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool FlipY
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return false;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Size.Y < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.Y > 0 && value || size.Y < 0 && !value)
|
||||
size.Y *= -1;
|
||||
view.Size = size;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅渲染选中
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool RenderSelectedOnly { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 显示坐标轴
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool ShowAxis { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 最大帧率
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public uint MaxFps
|
||||
{
|
||||
get => maxFps;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
renderWindow.SetFramerateLimit(value);
|
||||
maxFps = value;
|
||||
}
|
||||
}
|
||||
private uint maxFps = 60;
|
||||
|
||||
/// <summary>
|
||||
/// 获取 View
|
||||
/// </summary>
|
||||
public SFML.Graphics.View GetView() => renderWindow.GetView();
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启桌面投影
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool EnableDesktopProjection
|
||||
{
|
||||
get => enableDesktopProjection;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
if (enableDesktopProjection == value) return;
|
||||
if (value)
|
||||
{
|
||||
var screenBounds = Screen.FromControl(this).Bounds;
|
||||
Resolution = screenBounds.Size;
|
||||
wallpaperWindow.Position = new(screenBounds.X, screenBounds.Y);
|
||||
wallpaperForm.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
wallpaperForm.Hide();
|
||||
}
|
||||
enableDesktopProjection = value;
|
||||
}
|
||||
}
|
||||
private bool enableDesktopProjection = false;
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面背景色
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public SFML.Graphics.Color BackgroundColor { get; set; } = new(105, 105, 105);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 渲染管理
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面坐标轴颜色
|
||||
/// </summary>
|
||||
private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220);
|
||||
|
||||
/// <summary>
|
||||
/// 坐标轴顶点缓冲区
|
||||
/// </summary>
|
||||
private readonly SFML.Graphics.VertexArray axisVertices = new(SFML.Graphics.PrimitiveType.Lines, 2); // XXX: 暂时未使用 Dispose 释放
|
||||
|
||||
/// <summary>
|
||||
/// 渲染窗口
|
||||
/// </summary>
|
||||
private SFML.Graphics.RenderWindow renderWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 壁纸窗口
|
||||
/// </summary>
|
||||
private SFML.Graphics.RenderWindow wallpaperWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 帧间隔计时器
|
||||
/// </summary>
|
||||
private readonly SFML.System.Clock clock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 渲染任务
|
||||
/// </summary>
|
||||
private Task? task = null;
|
||||
private CancellationTokenSource? cancelToken = null;
|
||||
|
||||
/// <summary>
|
||||
/// 是否更新画面
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool IsUpdating
|
||||
{
|
||||
get => isUpdating;
|
||||
private set
|
||||
{
|
||||
if (value == isUpdating) return;
|
||||
if (value)
|
||||
{
|
||||
button_Start.ImageKey = "pause";
|
||||
}
|
||||
else
|
||||
{
|
||||
button_Start.ImageKey = "start";
|
||||
}
|
||||
isUpdating = value;
|
||||
}
|
||||
}
|
||||
private bool isUpdating = true;
|
||||
|
||||
/// <summary>
|
||||
/// 快进时间量
|
||||
/// </summary>
|
||||
private float forwardDelta = 0;
|
||||
private object _forwardDeltaLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 开始渲染
|
||||
/// </summary>
|
||||
public void StartRender()
|
||||
{
|
||||
// 延迟到第一次开启渲染时进行初始化
|
||||
if (renderWindow is null)
|
||||
{
|
||||
renderWindow = new(panel_Render.Handle);
|
||||
renderWindow.SetActive(false);
|
||||
wallpaperWindow = new(wallpaperForm.Handle);
|
||||
wallpaperWindow.SetActive(false);
|
||||
|
||||
// 设置默认参数
|
||||
Resolution = new(2048, 2048);
|
||||
Zoom = 1;
|
||||
Center = new(0, 0);
|
||||
FlipY = true;
|
||||
MaxFps = 30;
|
||||
}
|
||||
|
||||
if (task is not null) return;
|
||||
cancelToken = new();
|
||||
task = Task.Run(RenderTask, cancelToken.Token);
|
||||
IsUpdating = true;
|
||||
if (enableDesktopProjection) wallpaperForm.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止渲染
|
||||
/// </summary>
|
||||
public void StopRender()
|
||||
{
|
||||
if (wallpaperForm.InvokeRequired) wallpaperForm.Invoke(wallpaperForm.Hide);
|
||||
else wallpaperForm.Hide();
|
||||
IsUpdating = false;
|
||||
if (task is null || cancelToken is null)
|
||||
return;
|
||||
cancelToken.Cancel();
|
||||
task.Wait();
|
||||
cancelToken = null;
|
||||
task = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 渲染任务
|
||||
/// </summary>
|
||||
private void RenderTask()
|
||||
{
|
||||
try
|
||||
{
|
||||
renderWindow.SetActive(true);
|
||||
wallpaperWindow.SetActive(true);
|
||||
|
||||
float delta;
|
||||
while (cancelToken is not null && !cancelToken.IsCancellationRequested)
|
||||
{
|
||||
// 必须让 SFML 有机会处理窗口消息, 例如位置和大小变化
|
||||
renderWindow.DispatchEvents();
|
||||
|
||||
delta = clock.ElapsedTime.AsSeconds();
|
||||
clock.Restart();
|
||||
|
||||
// 停止更新的时候只是时间不前进, 但是坐标变换还是要更新, 否则无法移动对象
|
||||
if (!IsUpdating) delta = 0;
|
||||
|
||||
// 加上要快进的量
|
||||
lock (_forwardDeltaLock)
|
||||
{
|
||||
delta += forwardDelta;
|
||||
forwardDelta = 0;
|
||||
}
|
||||
|
||||
renderWindow.Clear(BackgroundColor);
|
||||
if (enableDesktopProjection) wallpaperWindow.Clear(BackgroundColor);
|
||||
|
||||
if (ShowAxis)
|
||||
{
|
||||
// 画一个很长的坐标轴, 用 1e9 比较合适
|
||||
axisVertices[0] = new(new(-1e9f, 0), AxisColor);
|
||||
axisVertices[1] = new(new(1e9f, 0), AxisColor);
|
||||
renderWindow.Draw(axisVertices);
|
||||
axisVertices[0] = new(new(0, -1e9f), AxisColor);
|
||||
axisVertices[1] = new(new(0, 1e9f), AxisColor);
|
||||
renderWindow.Draw(axisVertices);
|
||||
}
|
||||
|
||||
// 渲染 Spine
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines.Where(sp => !sp.IsHidden).ToArray();
|
||||
for (int i = spines.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (cancelToken is not null && cancelToken.IsCancellationRequested)
|
||||
break; // 提前中止
|
||||
|
||||
var spine = spines[i];
|
||||
|
||||
spine.Update(delta);
|
||||
|
||||
if (RenderSelectedOnly && !spine.IsSelected)
|
||||
continue;
|
||||
|
||||
spine.EnableDebug = true;
|
||||
renderWindow.Draw(spine);
|
||||
spine.EnableDebug = false;
|
||||
|
||||
if (enableDesktopProjection) wallpaperWindow.Draw(spine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderWindow.Display();
|
||||
|
||||
if (enableDesktopProjection) wallpaperWindow.Display();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Fatal(ex.ToString());
|
||||
logger.Fatal("Render task stopped");
|
||||
MessagePopup.Error(ex.ToString(), Properties.Resources.previewRenderStopped);
|
||||
}
|
||||
finally
|
||||
{
|
||||
renderWindow.SetActive(false);
|
||||
wallpaperWindow.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 画面拖放对象世界坐标源点
|
||||
/// </summary>
|
||||
private SFML.System.Vector2f? draggingSrc = null;
|
||||
|
||||
private void panel_RenderContainer_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
if (renderWindow is null) return;
|
||||
|
||||
float parentW = panel_Render.Parent.Width;
|
||||
float parentH = panel_Render.Parent.Height;
|
||||
float renderW = panel_Render.Width;
|
||||
float renderH = panel_Render.Height;
|
||||
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
||||
renderW *= scale;
|
||||
renderH *= scale;
|
||||
|
||||
panel_Render.Location = new((int)((parentW - renderW) / 2 + 0.5), (int)((parentH - renderH) / 2 + 0.5));
|
||||
panel_Render.Size = new((int)(renderW + 0.5), (int)(renderH + 0.5));
|
||||
}
|
||||
|
||||
private void panel_Render_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
// 右键优先级高, 进入画面拖动模式, 需要重新记录源点
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
draggingSrc = renderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
Cursor = Cursors.Hand;
|
||||
}
|
||||
// 按下了左键并且右键是松开的
|
||||
else if ((e.Button & MouseButtons.Left) != 0 && (MouseButtons & MouseButtons.Right) == 0)
|
||||
{
|
||||
draggingSrc = renderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
var src = new PointF(((SFML.System.Vector2f)draggingSrc).X, ((SFML.System.Vector2f)draggingSrc).Y);
|
||||
|
||||
if (SpineListView is null)
|
||||
return;
|
||||
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines;
|
||||
|
||||
// 仅渲染选中模式禁止在画面里选择对象
|
||||
if (RenderSelectedOnly)
|
||||
{
|
||||
// 只在被选中的对象里判断是否有效命中
|
||||
bool hit = false;
|
||||
foreach (int i in SpineListView.SelectedIndices)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
if (!spines[i].GetCurrentBounds().Contains(src)) continue;
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果没点到被选中的模型, 则不允许拖动
|
||||
if (!hit) draggingSrc = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ModifierKeys & Keys.Control) == 0)
|
||||
{
|
||||
// 没按 Ctrl 的情况下, 如果命中了已选中对象, 则就算普通命中
|
||||
bool hit = false;
|
||||
for (int i = 0; i < spines.Count; i++)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
if (!spines[i].GetCurrentBounds().Contains(src)) continue;
|
||||
|
||||
hit = true;
|
||||
|
||||
// 如果点到了没被选中的东西, 则清空原先选中的, 改为只选中这一次点的
|
||||
if (!SpineListView.SelectedIndices.Contains(i))
|
||||
{
|
||||
SpineListView.SelectedIndices.Clear();
|
||||
SpineListView.SelectedIndices.Add(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果点了空白的地方, 就清空选中列表
|
||||
if (!hit) SpineListView.SelectedIndices.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 按下 Ctrl 的情况就执行多选, 并且点空白处也不会清空选中
|
||||
for (int i = 0; i < spines.Count; i++)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
if (!spines[i].GetCurrentBounds().Contains(src)) continue;
|
||||
|
||||
SpineListView.SelectedIndices.Add(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_Render_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
if (draggingSrc is null) return;
|
||||
|
||||
var src = (SFML.System.Vector2f)draggingSrc;
|
||||
var dst = renderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
var _delta = dst - src;
|
||||
var delta = new SizeF(_delta.X, _delta.Y);
|
||||
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
Center -= delta;
|
||||
}
|
||||
else if ((e.Button & MouseButtons.Left) != 0)
|
||||
{
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines;
|
||||
foreach (int i in SpineListView.SelectedIndices)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
spines[i].Position += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
draggingSrc = dst;
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_Render_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
// 右键高优先级, 结束画面拖动模式
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
SpineListView?.SpinePropertyGrid?.Refresh();
|
||||
|
||||
draggingSrc = null;
|
||||
Cursor = Cursors.Default;
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
// 按下了左键并且右键是松开的
|
||||
else if ((e.Button & MouseButtons.Left) != 0 && (MouseButtons & MouseButtons.Right) == 0)
|
||||
{
|
||||
draggingSrc = null;
|
||||
SpineListView?.SpinePropertyGrid?.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_Render_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
var factor = (e.Delta > 0 ? 1.1f : 0.9f);
|
||||
if ((ModifierKeys & Keys.Control) == 0)
|
||||
{
|
||||
Zoom *= factor;
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines;
|
||||
foreach (int i in SpineListView.SelectedIndices)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
spines[i].Scale *= factor;
|
||||
}
|
||||
}
|
||||
SpineListView.SpinePropertyGrid?.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button_Stop_Click(object sender, EventArgs e)
|
||||
{
|
||||
IsUpdating = false;
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
foreach (var spine in SpineListView.Spines)
|
||||
spine.ResetAnimationsTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button_Restart_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
foreach (var spine in SpineListView.Spines)
|
||||
spine.ResetAnimationsTime();
|
||||
}
|
||||
}
|
||||
IsUpdating = true;
|
||||
}
|
||||
|
||||
private void button_Start_Click(object sender, EventArgs e)
|
||||
{
|
||||
IsUpdating = !IsUpdating;
|
||||
}
|
||||
|
||||
private void button_ForwardStep_Click(object sender, EventArgs e)
|
||||
{
|
||||
lock (_forwardDeltaLock)
|
||||
{
|
||||
if (maxFps > 0)
|
||||
forwardDelta += 1f / maxFps;
|
||||
else
|
||||
forwardDelta += 0.001f;
|
||||
}
|
||||
}
|
||||
|
||||
private void button_ForwardFast_Click(object sender, EventArgs e)
|
||||
{
|
||||
lock (_forwardDeltaLock)
|
||||
{
|
||||
if (maxFps > 0)
|
||||
forwardDelta += 10f / maxFps;
|
||||
else
|
||||
forwardDelta += 0.01f;
|
||||
}
|
||||
}
|
||||
|
||||
private void button_FullScreen_Click(object sender, EventArgs e)
|
||||
{
|
||||
var screenBounds = Screen.FromControl(this).Bounds;
|
||||
Resolution = screenBounds.Size;
|
||||
PropertyGrid?.Refresh();
|
||||
|
||||
// PerfMonitorV2 模式下, 位置和大小需要分开设置
|
||||
// 因为目标位置的 DPI 可能发生变化, 因此在 WM_POSITIONCHANGED 之后会收到 WM_DPICHANGED
|
||||
// 进而导致一次额外的 WM_SIZE 消息, 其大小是 DPI 修改前的大小, 这个消息在此次设置之后发生
|
||||
// 因此如果同时设置位置和大小则大小可能设置失败
|
||||
spinePreviewFullScreenForm.Location = screenBounds.Location;
|
||||
spinePreviewFullScreenForm.Size = screenBounds.Size;
|
||||
spinePreviewFullScreenForm.Controls.Add(panel_RenderContainer);
|
||||
spinePreviewFullScreenForm.Show();
|
||||
}
|
||||
|
||||
private void spinePreviewFullScreenForm_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Escape)
|
||||
{
|
||||
spinePreviewFullScreenForm.Hide();
|
||||
panel_ViewContainer.Controls.Add(panel_RenderContainer);
|
||||
}
|
||||
}
|
||||
|
||||
private void spinePreviewFullScreenForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
e.Cancel = e.CloseReason == CloseReason.UserClosing;
|
||||
}
|
||||
|
||||
private void wallpaperForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
e.Cancel = e.CloseReason == CloseReason.UserClosing;
|
||||
}
|
||||
|
||||
//public void ClickStopButton() => button_Stop_Click(button_Stop, EventArgs.Empty);
|
||||
//public void ClickRestartButton() => button_Restart_Click(button_Restart, EventArgs.Empty);
|
||||
//public void ClickStartButton() => button_Start_Click(button_Start, EventArgs.Empty);
|
||||
//public void ClickForwardStepButton() => button_ForwardStep_Click(button_ForwardStep, EventArgs.Empty);
|
||||
//public void ClickForwardFastButton() => button_ForwardFast_Click(button_ForwardFast, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于在 PropertyGrid 上显示 <see cref="SpinePreviewPanel"/> 属性的包装类, 提供用户操作接口
|
||||
/// </summary>
|
||||
public class SpinePreviewPanelProperty(SpinePreviewPanel previewPanel)
|
||||
{
|
||||
[Browsable(false)]
|
||||
public SpinePreviewPanel PreviewPanel { get; } = previewPanel;
|
||||
|
||||
[RefreshProperties(RefreshProperties.All)]
|
||||
[TypeConverter(typeof(ResolutionConverter))]
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayResolution")]
|
||||
public Size Resolution { get => PreviewPanel.Resolution; set => PreviewPanel.Resolution = value; }
|
||||
|
||||
[TypeConverter(typeof(PointFConverter))]
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayCenter")]
|
||||
public PointF Center { get => PreviewPanel.Center; set => PreviewPanel.Center = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayZoom")]
|
||||
public float Zoom { get => PreviewPanel.Zoom; set => PreviewPanel.Zoom = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayRotation")]
|
||||
public float Rotation { get => PreviewPanel.Rotation; set => PreviewPanel.Rotation = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayFlipHorizontal")]
|
||||
public bool FlipX { get => PreviewPanel.FlipX; set => PreviewPanel.FlipX = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayFlipVertical")]
|
||||
public bool FlipY { get => PreviewPanel.FlipY; set => PreviewPanel.FlipY = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayRenderSelected")]
|
||||
public bool RenderSelectedOnly { get => PreviewPanel.RenderSelectedOnly; set => PreviewPanel.RenderSelectedOnly = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryExport")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayShowAxis")]
|
||||
public bool ShowAxis { get => PreviewPanel.ShowAxis; set => PreviewPanel.ShowAxis = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryExport")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayMaximumFrameRate")]
|
||||
public uint MaxFps { get => PreviewPanel.MaxFps; set => PreviewPanel.MaxFps = value; }
|
||||
|
||||
[Editor(typeof(SFMLColorEditor), typeof(UITypeEditor))]
|
||||
[TypeConverter(typeof(SFMLColorConverter))]
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryExport")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayBackgroundColor")]
|
||||
public SFML.Graphics.Color BackgroundColor { get => PreviewPanel.BackgroundColor; set => PreviewPanel.BackgroundColor = value; }
|
||||
}
|
||||
}
|
||||
403
SpineViewer/Controls/SpinePreviewPanel.en.resx
Normal file
403
SpineViewer/Controls/SpinePreviewPanel.en.resx
Normal file
@@ -0,0 +1,403 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="panel_Render.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>157, 136</value>
|
||||
</data>
|
||||
<data name="panel_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>320, 320</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>641, 636</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>101, 598</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>438, 38</value>
|
||||
</data>
|
||||
<data name="imageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA8iMAAAJNU0Z0AUkBTAIBAQcB
|
||||
AAG4AQABuAEAAR8BAAEYAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABfAMAATADAAEBAQABIAYAAV0+
|
||||
AAMEAQUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/A1UB
|
||||
sWQAA1kB7wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/Ay0BRbcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9cAANEAXgDAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/swAB/wMAAf8DAAH/AwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/BwAB/wMAAf8DAAH/AwAB/wMAAf9XAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf+vAAH/AwAB/wNRAaQnAAH/AwAB/wMAAf8DAAH/MwAB/wMAAf8IAANOAZcDAAH/AwAB/wMAAf8D
|
||||
AAH/Ay4BSE8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB/+AAAxUBHQMAAf8DAAH/AwAB/y8AAf8DAAH/EwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf/kAAMmATgDAAH/AwAB/wMAAf8r
|
||||
AAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8DAAH/QwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/6wAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAANIAfYDAAH/AwAB/wMAAf8DAAH/AwQBBTsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/+8AAf8DAAH/AwAB/ycAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf/vAAH/AwAB/wMAAf8nAAH/AwAB/ygAAwcBCQMAAf8DAAH/AwAB/wMAAf8DYAHjLwAB/wMAAf8D
|
||||
AAH/SwAB/wMAAf8DAAH/7AADIAEtAwAB/wMAAf8nAAH/AwAB/zMAAf8DAAH/AwAB/wMAAf8DAAH/KwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/8wAB/wMAAf8nAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf9LAAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/PAADPwFsAwAB/wMAAf8nAAH/AwAB/wMAAf9L
|
||||
AAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB/0sAAf8D
|
||||
AAH/AwAB/5sAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/NAADCAEKAwAB/wMAAf8nAAH/AwAB
|
||||
/zAAA10BzgMAAf8DAAH/AwAB/wMAAf8EAScAAf8DAAH/AwAB/0sAAf8DAAH/AwAB/5QAAwUBBgMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/zMAAf8DAAH/AwAB/ycAAf8DAAH/LwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8vAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8nAAH/AwAB/ycAAf8DAAH/AwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8PAAH/AwAB/wMAAf8DFQEcLwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAAM9AWkDAAH/AwAB/wMAAf8DAAH/A0MBdjsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/5QAAwUBBgMAAf8DAAH/CwAB/wMAAf8DAAH/AxMBGjMAAf8DAAH/AwAB/ysAAf8DAAH/GwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf9DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wMbASYzAAH/AwAB/wMAAf8vAAH/AwAB/xMAAf8DAAH/AwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/SwAB
|
||||
/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMdASgkAANcAe4DAAH/AwAB
|
||||
/wMAAf8EAS8AAf8DAAH/CAADGAEhAwAB/wMAAf8DAAH/AwAB/wNcActPAAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/A2AB4wMAAf8DAAH/AwAB/wMAAf8DUAGfFwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf83AAH/AwAB/wcAAf8DAAH/AwAB/wMAAf8DAAH/VwAB/wMAAf8DAAH/AwAB/wMqAUAD
|
||||
KgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUAD
|
||||
AAH/AwAB/wMAAf8DAAH/mwAB/wMAAf8DAAH/Ax0BKQQAAwIBAwMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DBwEJWAAD
|
||||
WQHDAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/5wAAxIBFwMAAf8UAANKAYkDAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/AyEB+2cAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNbAcXIAANGAYADWgG/Ay4BSFQAA1oBv3QAA0YBgANaAb8DWgG/A1oBvwNaAb8DWgG/A1oB
|
||||
vwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DLgFIpwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADPQFpAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/EwAB/wMAAf8DAAH/LwAB/wMAAf8DAAH/KAADGQEiAwAB/wMAAf8jAAH/AwAB/wMAAf8oAAM/AW0D
|
||||
AAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADAwEEAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DAAH/AwAB/yQAA1YBtgMAAf8DAAH/AwAB
|
||||
/wMAAf8kAAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AwAB/wMAAf8DPwH4IwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/IAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8gAAM+AfkDAAH/AwAB/xwAA1oB
|
||||
8QMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/x8AAf8DAAH/AwAB/zcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxUB/jMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNZAbsYAANWAbUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DUQGeGAADPgH5AwAB/wMAAf8c
|
||||
AANaAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A1ABnRcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB
|
||||
/wMAAf8rAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAz4B+QMAAf8D
|
||||
AAH/HAADWgHxAwAB/wMAAf8DEQEWBAEDAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/zcAAf8D
|
||||
AAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswcAAf8D
|
||||
AAH/AwAB/wMAAf8jAAH/AwAB/wMAAf8DAAH/BwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAANWAbUDAAH/AwAB/wMzAVAHAAH/AwAB/wMAAf8DAAH/AwAB/xAAAz4B
|
||||
+QMAAf8DAAH/HAADWgHxAwAB/wMAAf8DEQEWCwAB/wMAAf8DAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wNWAbML
|
||||
AAH/AwAB/wMAAf8DFQH+GwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/Az0B
|
||||
aAgAA2AB2wMAAf8DAAH/AwAB/wMAAf8MAANWAbUDAAH/AwAB/wMzAVAIAANgAeMDAAH/AwAB/wMAAf8D
|
||||
AAH/DAADPgH5AwAB/wMAAf8cAANaAfEDAAH/AwAB/wMRARYMAAMzAVIDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/A1YBsw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/DAAD
|
||||
VAGrAwAB/wMAAf8DPQFoDAADJQE3AwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAzIB
|
||||
TwMAAf8DAAH/AwAB/wMAAf8IAAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxUB/gMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xAAAwwBDwMAAf8D
|
||||
SAH2DAADVAGrAwAB/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8D
|
||||
AAH/AwAB/wMAAf8EAAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFhgAA1oB6QMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/0cAAf8DAAH/AwAB/wMVAf4DAAH/AwAB/wMAAf8DAAH/LAADVAGrAwAB/wMAAf8DPQFoGwAB/wMAAf8D
|
||||
AAH/AwAB/wNdAc4DAAH/AwAB/wMzAVAbAAH/AwAB/wMAAf8DAAH/AykB+gMAAf8DAAH/HAADWgHxAwAB
|
||||
/wMAAf8DEQEWIwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8wAANUAasDAAH/AwAB/wM9AWgf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMwFQHwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/HAADWgHxAwAB
|
||||
/wMAAf8DEQEWJwAB/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/08AAf8DAAH/AwAB/wMAAf80AANUAasDAAH/AwAB/wM9AWgjAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMzAVAjAAH/AwAB/wMAAf8DAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFisAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxUB/jAAA1QBqwMAAf8DAAH/Az0BaB8AAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMzAVAf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8cAANaAfEDAAH/AwAB/wMRARYkAANcAdkDAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf9HAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/ywAA1QBqwMAAf8DAAH/Az0BaBsAAf8DAAH/AwAB/wMAAf8DWgHxAwAB
|
||||
/wMAAf8DMwFQGwAB/wMAAf8DAAH/AwAB/wMVAf4DAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFiMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8D
|
||||
AAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xcAAf8DWAG4DAADVAGrAwAB
|
||||
/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8DAAH/AwAB/wMAAf8E
|
||||
AAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFhgAAzABSgMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YB
|
||||
sw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DFQH+DwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
PQFoEwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAwkBDAMAAf8DAAH/AwAB/wMAAf8I
|
||||
AAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB/wMAAf8DAAH/AyoB/QMAAf8D
|
||||
AAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/JwAB/wMAAf8D
|
||||
VgGzCwAB/wMAAf8DAAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8MAANUAasDAAH/AwAB
|
||||
/wM9AWgIAAM6AWADAAH/AwAB/wMAAf8DAAH/DAADVgG1AwAB/wMAAf8DMwFQCAADSwGMAwAB/wMAAf8D
|
||||
AAH/AwAB/wwAAz4B+QMAAf8DAAH/HAADWgHxAwAB/wMAAf8DEQEWDAADBwEJAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8HAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wNWAbMHAAH/AwAB/wMAAf8DAAH/IwAB/wMAAf8DAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wwAA1QBqwMAAf8DAAH/Az0BaAcAAf8DAAH/AwAB/wMAAf8DAAH/EAADVgG1AwAB/wMAAf8DMwFQBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFgsAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A08BmQsAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB/wMAAf8rAAH/AwAB/wMAAf8DFQH+AwAB
|
||||
/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8DAAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB
|
||||
/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAz4B+QMAAf8DAAH/HAADWgHxAwAB/wMAAf8DEQEWBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DUwH0GAADVgG1AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A10B7BgAAz4B+QMAAf8DAAH/HAADWgHxAwAB/wMAAf8DYQHrAwAB/wMAAf8DAAH/AwAB
|
||||
/wNTAfQXAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DQwF3HAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8DMAFMHAADPgH5AwAB/wMAAf8c
|
||||
AANaAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8fAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8DKgFAAyoB
|
||||
QAMqAUADAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8DKgFAAyoBQAMqAUADAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8bAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwYBCCAAA1YBtgMAAf8DAAH/AwAB/wMAAf8DAgEDIAAD
|
||||
PgH5AwAB/wMAAf8cAANaAfEDAAH/AwAB/wMAAf8DAAH/AwAB/yMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xQAA0wBkAMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/y8AAf8DAAH/AwAB/ygAAzYBWAMAAf8DAAH/IwAB
|
||||
/wMAAf8DAAH/Aw0BESQAA1UBrQMAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8sAANaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DFQEcGAAD
|
||||
TwGZA1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvxgAA04BlzQAA0sBjTAAAwwBDygAA1ABmjAAAygB
|
||||
PEAAAzgBWwNaAb8DWgG/A1oBvwMwAUwYAANEAXoDWgG/A1oBvwNaAb8DIAEtHAABQgFNAT4HAAE+AwAB
|
||||
KAMAAXwDAAEwAwABAQEAAQEGAAEDFgAD/wEAAf8B4AEHAf8B+AE/Av8B4AIAAXgEAAH/AcABAQH/AfgB
|
||||
HwL/AcACAAF4BAAB/wGDAeAB/wH5AQcC/wHAAgABOAQAAf8BjwH4AX8B+QGBAv8BxwH/Af4BOAQAAv8B
|
||||
/AE/AfkB4AL/AccB/wH+ATgEAAL/Af4BHwH5AfgBPwH/AccB/wH+ATgEAAP/AR8B+QH8AQ8B/wHHAf8B
|
||||
/gE4BAAD/wGPAfkB/wEHAf8BxwH/Af4BOAQAA/8BjwH5Af8BgQH/AccB/wH+ATgEAAP/AY8B+QH/AeAB
|
||||
/wHHAf8B/gE4BAAD/wHPAfkB/wH4AX8BxwH/Af4BOAQAA/8BzwH5Af8B/AF/AccB/wH+ATgEAAP/Ac8B
|
||||
+QH/AfgBfwHHAf8B/gE4BAAB8AEPAf8BjwH5Af8B4AF/AccB/wH+ATgEAAHgAQcB/wGPAfkB/wHBAf8B
|
||||
xwH/Af4BOAQAAeABBwH/AY8B+QH/AQcB/wHHAf8B/gE4BAAB4wGHAf8BHwH5AfwBDwH/AccB/wH+ATgE
|
||||
AAHjAQ8B/wEfAfkB+AE/Af8BxwH/Af4BOAQAAeIBHwH+AT8B+QHgAv8BxwH/Af4BOAQAAeABDwH4AT8B
|
||||
+QGBAv8BxwH/Af4BOAQAAeABAwHgAf8B+QEHAv8BwAIAATgEAAHwAYABAQH/AfgBDwL/AcACAAF4BAAB
|
||||
8wHgAQcB/wH4AT8C/wHgAgABeAQAAf8B/gE/Af8B/gP/AfgBAAEBAfgEAAHwAQcBwAEPAR8B/AF/AeMB
|
||||
/AF/AeMB/wHwAR4BAwLwAQcBwAEOAQ8B+AE/AeMB+AEfAeMB/wHgAQwBAQLwAX8B/gEOAQcB+AEfAeMB
|
||||
+AEPAeMB/wHgAQwBAQLwAT8B/AEOAQEB+AEHAeMB+AEDAeMB/wHjAYwBcQLwAR8B+AEOAQAB+AEDAeMB
|
||||
+AEBAeMB/wHjAYwBcQHwAfEBDwHwAY4BEAF4AUEB4wH4AWAB4wH/AeMBjAFxAfAB8QGHAeEBjgEYATgB
|
||||
YAHjAfgBcAEjAf8B4wGMAXEB8AHxAsMBjgEcARgBcAFjAfgBfAEDAf8B4wGMAXEB8AHzAeEBhwGOAR8B
|
||||
CAF8ASMB+AF+AQMB/wHjAYwBcQHwAf8B8AEPAf4BHwGAAX4BAwH4AX8BgwH/AeMBjAFxAfAB/wH4AR8B
|
||||
/gEfAcABfwEDAfgBfwHDAf8B4wGMAXEB8AH/AfwBPwH+AR8B4AF/AYMB+AF/AeMB/wHjAYwBcQHwAf8B
|
||||
+AEfAf4BHwHAAX8BAwH4AX8BwwH/AeMBjAFxAfAB/wHwAQ8B/gEfAYABfgEDAfgBfwGDAf8B4wGMAXEB
|
||||
8AHzAeEBhwHOAR8BCAF8ASMB+AF+AQMB/wHjAYwBcQHwAfECwwGOAR4BGAFwAWMB+AF8AQMB/wHjAYwB
|
||||
cQHwAfEBhwHhAY4BGAE4AWAB4wH4AXABIwH/AeMBjAFxAfAB8QEPAfABjgEQAXgBQQHjAfgBYAFjAf8B
|
||||
4wGMAXEC8AEfAfgBDgEAAfgBAwHjAfgBQQHjAf8B4wGMAXEC8AE/AfwBDgEBAfgBBwHjAfgBAwHjAf8B
|
||||
4wGMAXEC8AF/Af4BDgEDAfgBDwHjAfgBDwHjAf8B4AEMAQEC8AEHAeABDgEHAfgBHwHjAfgBHwHjAf8B
|
||||
4AEMAQEC8AEHAcABDwEfAfwBfwHjAfwBPwHjAf8B8AEeAQMB8AH4AQcB4AEfAb8B/gH/AfcB/gH/AfcB
|
||||
/wH4AT8BBwHwCw==
|
||||
</value>
|
||||
</data>
|
||||
<data name="button_Stop.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 2</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Stop.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_Stop.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_Stop.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_Stop.ToolTip" xml:space="preserve">
|
||||
<value>Stop playback and reset time.</value>
|
||||
</data>
|
||||
<data name="button_Restart.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>76, 2</value>
|
||||
</data>
|
||||
<data name="button_Restart.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_Restart.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_Restart.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_Restart.ToolTip" xml:space="preserve">
|
||||
<value>Play from the beginning.</value>
|
||||
</data>
|
||||
<data name="button_Start.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>149, 2</value>
|
||||
</data>
|
||||
<data name="button_Start.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_Start.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_Start.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_Start.ToolTip" xml:space="preserve">
|
||||
<value>Play/Pause</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>222, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.ToolTip" xml:space="preserve">
|
||||
<value>Fast forward 1 frame</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>295, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.ToolTip" xml:space="preserve">
|
||||
<value>Fast forward 10 frames.</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>368, 2</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.ToolTip" xml:space="preserve">
|
||||
<value>Fullscreen preview.</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>641, 598</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>641, 598</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>11, 24</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>641, 636</value>
|
||||
</data>
|
||||
</root>
|
||||
765
SpineViewer/Controls/SpinePreviewPanel.resx
Normal file
765
SpineViewer/Controls/SpinePreviewPanel.resx
Normal file
@@ -0,0 +1,765 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="button_ForwardStep.ImageKey" xml:space="preserve">
|
||||
<value>forward-step</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="spinePreviewFullScreenForm.Visible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardFast.Name" xml:space="preserve">
|
||||
<value>button_ForwardFast</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardFast.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>panel_ViewContainer.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Restart.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="button_Start.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name=">>toolTip.Name" xml:space="preserve">
|
||||
<value>toolTip</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Start.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Start.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.ImageKey" xml:space="preserve">
|
||||
<value>arrows-maximize</value>
|
||||
</data>
|
||||
<data name=">>spinePreviewFullScreenForm.Type" xml:space="preserve">
|
||||
<value>SpineViewer.Forms.SpinePreviewFullScreenForm, SpineViewer, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>wallpaperForm.Name" xml:space="preserve">
|
||||
<value>wallpaperForm</value>
|
||||
</data>
|
||||
<data name="button_Restart.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>466, 530</value>
|
||||
</data>
|
||||
<data name=">>button_Restart.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_Restart.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>65, 2</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="button_Start.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name=">>panel_RenderContainer.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name="button_Start.ImageKey" xml:space="preserve">
|
||||
<value>pause</value>
|
||||
</data>
|
||||
<data name="panel_Render.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>114, 113</value>
|
||||
</data>
|
||||
<data name="button_Start.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>panel_ViewContainer.Name" xml:space="preserve">
|
||||
<value>panel_ViewContainer</value>
|
||||
</data>
|
||||
<data name="button_Stop.ToolTip" xml:space="preserve">
|
||||
<value>停止播放并重置时间到初始</value>
|
||||
</data>
|
||||
<data name="button_Restart.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name=">>panel_Render.Name" xml:space="preserve">
|
||||
<value>panel_Render</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>SpinePreviewPanel</value>
|
||||
</data>
|
||||
<data name=">>button_Stop.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardFast.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>panel_Render.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="spinePreviewFullScreenForm.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>2560, 1440</value>
|
||||
</data>
|
||||
<data name=">>panel_Render.Parent" xml:space="preserve">
|
||||
<value>panel_RenderContainer</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>panel_RenderContainer.Parent" xml:space="preserve">
|
||||
<value>panel_ViewContainer</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="wallpaperForm.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name=">>button_ForwardStep.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_ForwardStep.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="panel_Render.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>button_Stop.Name" xml:space="preserve">
|
||||
<value>button_Stop</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button_FullScreen.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>imageList.Name" xml:space="preserve">
|
||||
<value>imageList</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardFast.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Stop.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>466, 492</value>
|
||||
</data>
|
||||
<data name="button_Restart.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>254, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Start.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>378, 38</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="panel_Render.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardStep.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name=">>imageList.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_Restart.ToolTip" xml:space="preserve">
|
||||
<value>从头开始播放</value>
|
||||
</data>
|
||||
<data name=">>button_FullScreen.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="panel_Render.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="button_ForwardFast.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="button_Start.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>128, 2</value>
|
||||
</data>
|
||||
<data name="spinePreviewFullScreenForm.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name=">>button_Start.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Restart.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>466, 492</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.ToolTip" xml:space="preserve">
|
||||
<value>快进 1 帧</value>
|
||||
</data>
|
||||
<data name=">>button_Stop.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.ToolTip" xml:space="preserve">
|
||||
<value>快进 10 帧</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>None</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>317, 2</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardStep.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="button_ForwardFast.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>button_Restart.Name" xml:space="preserve">
|
||||
<value>button_Restart</value>
|
||||
</data>
|
||||
<data name="button_Stop.ImageKey" xml:space="preserve">
|
||||
<value>stop</value>
|
||||
</data>
|
||||
<data name="panel_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>233, 267</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="wallpaperForm.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>Manual</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>panel_ViewContainer.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_Stop.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name=">>wallpaperForm.Type" xml:space="preserve">
|
||||
<value>SpineViewer.WallpaperForm, SpineViewer, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name="button_Stop.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 2</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.ToolTip" xml:space="preserve">
|
||||
<value>全屏预览</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Stop.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>panel_RenderContainer.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Stop.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="flowLayoutPanel1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="panel_ViewContainer" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="button_FullScreen.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>button_FullScreen.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="button_Stop.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_Restart.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Stop.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardStep.Name" xml:space="preserve">
|
||||
<value>button_ForwardStep</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>191, 2</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>44, 492</value>
|
||||
</data>
|
||||
<data name="$this.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="imageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA9CMAAAJNU0Z0AUkBTAIBAQcB
|
||||
AAGkAQABrAEAAR8BAAEYAQAE/wEhARAI/wFCAU0BNgcAATYDAAEoAwABfAMAATADAAEBAQABIAYAAV0+
|
||||
AAMEAQUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/A1UB
|
||||
sWQAA1kB7wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/Ay0BRbcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9cAANEAXgDAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/swAB/wMAAf8DAAH/AwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/BwAB/wMAAf8DAAH/AwAB/wMAAf9XAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf+vAAH/AwAB/wNRAaQnAAH/AwAB/wMAAf8DAAH/MwAB/wMAAf8IAANOAZcDAAH/AwAB/wMAAf8D
|
||||
AAH/Ay4BSE8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB/+AAAxUBHQMAAf8DAAH/AwAB/y8AAf8DAAH/EwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf/kAAMmATgDAAH/AwAB/wMAAf8r
|
||||
AAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8DAAH/QwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/6wAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAANEAfYDAAH/AwAB/wMAAf8DAAH/AwQBBTsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/+8AAf8DAAH/AwAB/ycAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf/vAAH/AwAB/wMAAf8nAAH/AwAB/ygAAwcBCQMAAf8DAAH/AwAB/wMAAf8DYAHjLwAB/wMAAf8D
|
||||
AAH/SwAB/wMAAf8DAAH/7AADIAEtAwAB/wMAAf8nAAH/AwAB/zMAAf8DAAH/AwAB/wMAAf8DAAH/KwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/8wAB/wMAAf8nAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf9LAAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/PAADPwFsAwAB/wMAAf8nAAH/AwAB/wMAAf9L
|
||||
AAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB/0sAAf8D
|
||||
AAH/AwAB/5sAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/NAADCAEKAwAB/wMAAf8nAAH/AwAB
|
||||
/zAAA10BzgMAAf8DAAH/AwAB/wMAAf8EAScAAf8DAAH/AwAB/0sAAf8DAAH/AwAB/5QAAwUBBgMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/zMAAf8DAAH/AwAB/ycAAf8DAAH/LwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8vAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8nAAH/AwAB/ycAAf8DAAH/AwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8PAAH/AwAB/wMAAf8DFQEcLwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAAM9AWkDAAH/AwAB/wMAAf8DAAH/A0MBdjsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/5QAAwUBBgMAAf8DAAH/CwAB/wMAAf8DAAH/AxMBGjMAAf8DAAH/AwAB/ysAAf8DAAH/GwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf9DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wMbASYzAAH/AwAB/wMAAf8vAAH/AwAB/xMAAf8DAAH/AwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/SwAB
|
||||
/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMdASgkAANaAe4DAAH/AwAB
|
||||
/wMAAf8EAS8AAf8DAAH/CAADGAEhAwAB/wMAAf8DAAH/AwAB/wNcActPAAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/A2AB4wMAAf8DAAH/AwAB/wMAAf8DUAGfFwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf83AAH/AwAB/wcAAf8DAAH/AwAB/wMAAf8DAAH/VwAB/wMAAf8DAAH/AwAB/wMqAUAD
|
||||
KgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUAD
|
||||
AAH/AwAB/wMAAf8DAAH/mwAB/wMAAf8DAAH/Ax0BKQQAAwIBAwMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DBwEJWAAD
|
||||
WQHDAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/5wAAxIBFwMAAf8UAANKAYkDAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/AyEB+2cAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNbAcXIAANGAYADWgG/Ay4BSFQAA1oBv3QAA0YBgANaAb8DWgG/A1oBvwNaAb8DWgG/A1oB
|
||||
vwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DLgFIpwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADPQFpAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/EwAB/wMAAf8DAAH/LwAB/wMAAf8DAAH/KAADGQEiAwAB/wMAAf8jAAH/AwAB/wMAAf8oAAM/AW0D
|
||||
AAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADAwEEAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DAAH/AwAB/yQAA1YBtgMAAf8DAAH/AwAB
|
||||
/wMAAf8kAAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AwAB/wMAAf8DPQH4IwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/IAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8gAAM4AfkDAAH/AwAB/xwAA1gB
|
||||
8QMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/x8AAf8DAAH/AwAB/zcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxMB/jMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNZAbsYAANWAbUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DUQGeGAADOAH5AwAB/wMAAf8c
|
||||
AANYAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A1ABnRcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB
|
||||
/wMAAf8rAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAzgB+QMAAf8D
|
||||
AAH/HAADWAHxAwAB/wMAAf8DEQEWBAEDAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/zcAAf8D
|
||||
AAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswcAAf8D
|
||||
AAH/AwAB/wMAAf8jAAH/AwAB/wMAAf8DAAH/BwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAANWAbUDAAH/AwAB/wMzAVAHAAH/AwAB/wMAAf8DAAH/AwAB/xAAAzgB
|
||||
+QMAAf8DAAH/HAADWAHxAwAB/wMAAf8DEQEWCwAB/wMAAf8DAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wNWAbML
|
||||
AAH/AwAB/wMAAf8DEwH+GwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/Az0B
|
||||
aAgAA2AB2wMAAf8DAAH/AwAB/wMAAf8MAANWAbUDAAH/AwAB/wMzAVAIAANgAeMDAAH/AwAB/wMAAf8D
|
||||
AAH/DAADOAH5AwAB/wMAAf8cAANYAfEDAAH/AwAB/wMRARYMAAMzAVIDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/A1YBsw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/DAAD
|
||||
VAGrAwAB/wMAAf8DPQFoDAADJQE3AwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAzIB
|
||||
TwMAAf8DAAH/AwAB/wMAAf8IAAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxMB/gMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xAAAwwBDwMAAf8D
|
||||
RAH2DAADVAGrAwAB/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8D
|
||||
AAH/AwAB/wMAAf8EAAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFhgAA1oB6QMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/0cAAf8DAAH/AwAB/wMTAf4DAAH/AwAB/wMAAf8DAAH/LAADVAGrAwAB/wMAAf8DPQFoGwAB/wMAAf8D
|
||||
AAH/AwAB/wNdAc4DAAH/AwAB/wMzAVAbAAH/AwAB/wMAAf8DAAH/AycB+gMAAf8DAAH/HAADWAHxAwAB
|
||||
/wMAAf8DEQEWIwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8wAANUAasDAAH/AwAB/wM9AWgf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMwFQHwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/HAADWAHxAwAB
|
||||
/wMAAf8DEQEWJwAB/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/08AAf8DAAH/AwAB/wMAAf80AANUAasDAAH/AwAB/wM9AWgjAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMzAVAjAAH/AwAB/wMAAf8DAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFisAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxMB/jAAA1QBqwMAAf8DAAH/Az0BaB8AAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMzAVAf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8cAANYAfEDAAH/AwAB/wMRARYkAANcAdkDAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf9HAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/ywAA1QBqwMAAf8DAAH/Az0BaBsAAf8DAAH/AwAB/wMAAf8DWAHxAwAB
|
||||
/wMAAf8DMwFQGwAB/wMAAf8DAAH/AwAB/wMTAf4DAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFiMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8D
|
||||
AAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xcAAf8DWAG4DAADVAGrAwAB
|
||||
/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8DAAH/AwAB/wMAAf8E
|
||||
AAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFhgAAzABSgMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YB
|
||||
sw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DEwH+DwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
PQFoEwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAwkBDAMAAf8DAAH/AwAB/wMAAf8I
|
||||
AAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB/wMAAf8DAAH/AyYB/QMAAf8D
|
||||
AAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/JwAB/wMAAf8D
|
||||
VgGzCwAB/wMAAf8DAAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8MAANUAasDAAH/AwAB
|
||||
/wM9AWgIAAM6AWADAAH/AwAB/wMAAf8DAAH/DAADVgG1AwAB/wMAAf8DMwFQCAADSwGMAwAB/wMAAf8D
|
||||
AAH/AwAB/wwAAzgB+QMAAf8DAAH/HAADWAHxAwAB/wMAAf8DEQEWDAADBwEJAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8HAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wNWAbMHAAH/AwAB/wMAAf8DAAH/IwAB/wMAAf8DAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wwAA1QBqwMAAf8DAAH/Az0BaAcAAf8DAAH/AwAB/wMAAf8DAAH/EAADVgG1AwAB/wMAAf8DMwFQBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFgsAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A08BmQsAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB/wMAAf8rAAH/AwAB/wMAAf8DEwH+AwAB
|
||||
/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8DAAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB
|
||||
/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAzgB+QMAAf8DAAH/HAADWAHxAwAB/wMAAf8DEQEWBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DTwH0GAADVgG1AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A10B7BgAAzgB+QMAAf8DAAH/HAADWAHxAwAB/wMAAf8DYQHrAwAB/wMAAf8DAAH/AwAB
|
||||
/wNPAfQXAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DQwF3HAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8DMAFMHAADOAH5AwAB/wMAAf8c
|
||||
AANYAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8fAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8DKgFAAyoB
|
||||
QAMqAUADAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8DKgFAAyoBQAMqAUADAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8bAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwYBCCAAA1YBtgMAAf8DAAH/AwAB/wMAAf8DAgEDIAAD
|
||||
OAH5AwAB/wMAAf8cAANYAfEDAAH/AwAB/wMAAf8DAAH/AwAB/yMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xQAA0wBkAMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/y8AAf8DAAH/AwAB/ygAAzYBWAMAAf8DAAH/IwAB
|
||||
/wMAAf8DAAH/Aw0BESQAA1UBrQMAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8sAANaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DFQEcGAAD
|
||||
TwGZA1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvxgAA04BlzQAA0sBjTAAAwwBDygAA1ABmjAAAygB
|
||||
PEAAAzgBWwNaAb8DWgG/A1oBvwMwAUwYAANEAXoDWgG/A1oBvwNaAb8DIAEtHAABQgFNAT4HAAE+AwAB
|
||||
KAMAAXwDAAEwAwABAQEAAQEGAAEDFgAD/wEAAf8B4AEHAf8B+AE/Av8B4AIAAXgEAAH/AcABAQH/AfgB
|
||||
HwL/AcACAAF4BAAB/wGDAeAB/wH5AQcC/wHAAgABOAQAAf8BjwH4AX8B+QGBAv8BxwH/Af4BOAQAAv8B
|
||||
/AE/AfkB4AL/AccB/wH+ATgEAAL/Af4BHwH5AfgBPwH/AccB/wH+ATgEAAP/AR8B+QH8AQ8B/wHHAf8B
|
||||
/gE4BAAD/wGPAfkB/wEHAf8BxwH/Af4BOAQAA/8BjwH5Af8BgQH/AccB/wH+ATgEAAP/AY8B+QH/AeAB
|
||||
/wHHAf8B/gE4BAAD/wHPAfkB/wH4AX8BxwH/Af4BOAQAA/8BzwH5Af8B/AF/AccB/wH+ATgEAAP/Ac8B
|
||||
+QH/AfgBfwHHAf8B/gE4BAAB8AEPAf8BjwH5Af8B4AF/AccB/wH+ATgEAAHgAQcB/wGPAfkB/wHBAf8B
|
||||
xwH/Af4BOAQAAeABBwH/AY8B+QH/AQcB/wHHAf8B/gE4BAAB4wGHAf8BHwH5AfwBDwH/AccB/wH+ATgE
|
||||
AAHjAQ8B/wEfAfkB+AE/Af8BxwH/Af4BOAQAAeIBHwH+AT8B+QHgAv8BxwH/Af4BOAQAAeABDwH4AT8B
|
||||
+QGBAv8BxwH/Af4BOAQAAeABAwHgAf8B+QEHAv8BwAIAATgEAAHwAYABAQH/AfgBDwL/AcACAAF4BAAB
|
||||
8wHgAQcB/wH4AT8C/wHgAgABeAQAAf8B/gE/Af8B/gP/AfgBAAEBAfgEAAHwAQcBwAEPAR8B/AF/AeMB
|
||||
/AF/AeMB/wHwAR4BAwLwAQcBwAEOAQ8B+AE/AeMB+AEfAeMB/wHgAQwBAQLwAX8B/gEOAQcB+AEfAeMB
|
||||
+AEPAeMB/wHgAQwBAQLwAT8B/AEOAQEB+AEHAeMB+AEDAeMB/wHjAYwBcQLwAR8B+AEOAQAB+AEDAeMB
|
||||
+AEBAeMB/wHjAYwBcQHwAfEBDwHwAY4BEAF4AUEB4wH4AWAB4wH/AeMBjAFxAfAB8QGHAeEBjgEYATgB
|
||||
YAHjAfgBcAEjAf8B4wGMAXEB8AHxAsMBjgEcARgBcAFjAfgBfAEDAf8B4wGMAXEB8AHzAeEBhwGOAR8B
|
||||
CAF8ASMB+AF+AQMB/wHjAYwBcQHwAf8B8AEPAf4BHwGAAX4BAwH4AX8BgwH/AeMBjAFxAfAB/wH4AR8B
|
||||
/gEfAcABfwEDAfgBfwHDAf8B4wGMAXEB8AH/AfwBPwH+AR8B4AF/AYMB+AF/AeMB/wHjAYwBcQHwAf8B
|
||||
+AEfAf4BHwHAAX8BAwH4AX8BwwH/AeMBjAFxAfAB/wHwAQ8B/gEfAYABfgEDAfgBfwGDAf8B4wGMAXEB
|
||||
8AHzAeEBhwHOAR8BCAF8ASMB+AF+AQMB/wHjAYwBcQHwAfECwwGOAR4BGAFwAWMB+AF8AQMB/wHjAYwB
|
||||
cQHwAfEBhwHhAY4BGAE4AWAB4wH4AXABIwH/AeMBjAFxAfAB8QEPAfABjgEQAXgBQQHjAfgBYAFjAf8B
|
||||
4wGMAXEC8AEfAfgBDgEAAfgBAwHjAfgBQQHjAf8B4wGMAXEC8AE/AfwBDgEBAfgBBwHjAfgBAwHjAf8B
|
||||
4wGMAXEC8AF/Af4BDgEDAfgBDwHjAfgBDwHjAf8B4AEMAQEC8AEHAeABDgEHAfgBHwHjAfgBHwHjAf8B
|
||||
4AEMAQEC8AEHAcABDwEfAfwBfwHjAfwBPwHjAf8B8AEeAQMB8AH4AQcB4AEfAb8B/gH/AfcB/gH/AfcB
|
||||
/wH4AT8BBwHwFgAL
|
||||
</value>
|
||||
</data>
|
||||
<data name="spinePreviewFullScreenForm.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>Manual</value>
|
||||
</data>
|
||||
<data name="button_Restart.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>panel_Render.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_Stop.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_FullScreen.Name" xml:space="preserve">
|
||||
<value>button_FullScreen</value>
|
||||
</data>
|
||||
<data name=">>button_Start.Name" xml:space="preserve">
|
||||
<value>button_Start</value>
|
||||
</data>
|
||||
<data name="button_Start.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_Start.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>panel_ViewContainer.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="button_Restart.ImageKey" xml:space="preserve">
|
||||
<value>rotate-left</value>
|
||||
</data>
|
||||
<data name="button_Restart.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name="wallpaperForm.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name=">>panel_RenderContainer.Name" xml:space="preserve">
|
||||
<value>panel_RenderContainer</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="wallpaperForm.Visible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="button_Start.ToolTip" xml:space="preserve">
|
||||
<value>开始/暂停</value>
|
||||
</data>
|
||||
<data name="button_Start.BackgroundImageLayout" type="System.Windows.Forms.ImageLayout, System.Windows.Forms">
|
||||
<value>Center</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="button_ForwardFast.ImageKey" xml:space="preserve">
|
||||
<value>forward-fast</value>
|
||||
</data>
|
||||
<data name=">>toolTip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolTip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>466, 530</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>spinePreviewFullScreenForm.Name" xml:space="preserve">
|
||||
<value>spinePreviewFullScreenForm</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<metadata name="spinePreviewFullScreenForm.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>307, 18</value>
|
||||
</metadata>
|
||||
<metadata name="wallpaperForm.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>618, 18</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="imageList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>165, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
63
SpineViewer/Controls/SpinePreviewer.Designer.cs
generated
63
SpineViewer/Controls/SpinePreviewer.Designer.cs
generated
@@ -1,63 +0,0 @@
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
partial class SpinePreviewer
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 组件设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
panel = new Panel();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel
|
||||
//
|
||||
panel.BackColor = SystemColors.ControlDarkDark;
|
||||
panel.Location = new Point(160, 160);
|
||||
panel.Margin = new Padding(0);
|
||||
panel.Name = "panel";
|
||||
panel.Size = new Size(320, 320);
|
||||
panel.TabIndex = 1;
|
||||
panel.MouseDown += panel_MouseDown;
|
||||
panel.MouseMove += panel_MouseMove;
|
||||
panel.MouseUp += panel_MouseUp;
|
||||
panel.MouseWheel += panel_MouseWheel;
|
||||
//
|
||||
// SpinePreviewer
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
BackColor = SystemColors.ControlDark;
|
||||
Controls.Add(panel);
|
||||
Name = "SpinePreviewer";
|
||||
Size = new Size(640, 640);
|
||||
SizeChanged += SpinePreviewer_SizeChanged;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel;
|
||||
}
|
||||
}
|
||||
@@ -1,564 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Security.Policy;
|
||||
using System.Diagnostics;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
public partial class SpinePreviewer : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// 包装类, 用于属性面板显示
|
||||
/// </summary>
|
||||
private class PreviewerProperty(SpinePreviewer previewer)
|
||||
{
|
||||
[TypeConverter(typeof(SizeConverter))]
|
||||
[Category("导出"), DisplayName("分辨率")]
|
||||
public Size Resolution { get => previewer.Resolution; set => previewer.Resolution = value; }
|
||||
|
||||
[TypeConverter(typeof(PointFConverter))]
|
||||
[Category("导出"), DisplayName("画面中心点")]
|
||||
public PointF Center { get => previewer.Center; set => previewer.Center = value; }
|
||||
|
||||
[Category("导出"), DisplayName("缩放")]
|
||||
public float Zoom { get => previewer.Zoom; set => previewer.Zoom = value; }
|
||||
|
||||
[Category("导出"), DisplayName("旋转")]
|
||||
public float Rotation { get => previewer.Rotation; set => previewer.Rotation = value; }
|
||||
|
||||
[Category("导出"), DisplayName("水平翻转")]
|
||||
public bool FlipX { get => previewer.FlipX; set => previewer.FlipX = value; }
|
||||
|
||||
[Category("导出"), DisplayName("垂直翻转")]
|
||||
public bool FlipY { get => previewer.FlipY; set => previewer.FlipY = value; }
|
||||
|
||||
[Category("导出"), DisplayName("仅渲染选中")]
|
||||
public bool RenderSelectedOnly { get => previewer.RenderSelectedOnly; set => previewer.RenderSelectedOnly = value; }
|
||||
|
||||
[Category("预览"), DisplayName("显示坐标轴")]
|
||||
public bool ShowAxis { get => previewer.ShowAxis; set => previewer.ShowAxis = value; }
|
||||
|
||||
[Category("预览"), DisplayName("最大帧率")]
|
||||
public uint MaxFps { get => previewer.MaxFps; set => previewer.MaxFps = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 要绑定的 Spine 列表控件
|
||||
/// </summary>
|
||||
[Category("自定义"), Description("相关联的 SpineListView")]
|
||||
public SpineListView? SpineListView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 属性信息面板
|
||||
/// </summary>
|
||||
[Category("自定义"), Description("用于显示画面属性的属性页")]
|
||||
public PropertyGrid? PropertyGrid
|
||||
{
|
||||
get => propertyGrid;
|
||||
set
|
||||
{
|
||||
propertyGrid = value;
|
||||
if (propertyGrid is not null)
|
||||
propertyGrid.SelectedObject = new PreviewerProperty(this);
|
||||
}
|
||||
}
|
||||
private PropertyGrid? propertyGrid;
|
||||
|
||||
/// <summary>
|
||||
/// 画面缩放最大值
|
||||
/// </summary>
|
||||
public const float ZOOM_MAX = 1000f;
|
||||
|
||||
/// <summary>
|
||||
/// 画面缩放最小值
|
||||
/// </summary>
|
||||
public const float ZOOM_MIN = 0.001f;
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面背景色
|
||||
/// </summary>
|
||||
private static readonly SFML.Graphics.Color BackgroundColor = new(105, 105, 105);
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面坐标轴颜色
|
||||
/// </summary>
|
||||
private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220);
|
||||
|
||||
/// <summary>
|
||||
/// 坐标轴顶点缓冲区
|
||||
/// </summary>
|
||||
private readonly SFML.Graphics.VertexArray AxisVertex = new(SFML.Graphics.PrimitiveType.Lines, 2);
|
||||
|
||||
/// <summary>
|
||||
/// 渲染窗口
|
||||
/// </summary>
|
||||
private readonly SFML.Graphics.RenderWindow RenderWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 帧间隔计时器
|
||||
/// </summary>
|
||||
private readonly SFML.System.Clock Clock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 画面拖放对象世界坐标源点
|
||||
/// </summary>
|
||||
private SFML.System.Vector2f? draggingSrc = null;
|
||||
|
||||
/// <summary>
|
||||
/// 渲染任务
|
||||
/// </summary>
|
||||
private Task? task = null;
|
||||
private CancellationTokenSource? cancelToken = null;
|
||||
|
||||
/// <summary>
|
||||
/// 分辨率
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public Size Resolution
|
||||
{
|
||||
get => resolution;
|
||||
set
|
||||
{
|
||||
if (value.Width <= 0) value.Width = 100;
|
||||
if (value.Height <= 0) value.Height = 100;
|
||||
|
||||
float parentX = Width;
|
||||
float parentY = Height;
|
||||
float sizeX = value.Width;
|
||||
float sizeY = value.Height;
|
||||
|
||||
if ((sizeY / sizeX) < (parentY / parentX))
|
||||
{
|
||||
// 相同的 X, 子窗口 Y 更小
|
||||
sizeY = parentX * sizeY / sizeX;
|
||||
sizeX = parentX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 相同的 Y, 子窗口 X 更小
|
||||
sizeX = parentY * sizeX / sizeY;
|
||||
sizeY = parentY;
|
||||
}
|
||||
|
||||
// 必须通过 SFML 的方法调整窗口
|
||||
RenderWindow.Position = new((int)(parentX - sizeX) / 2, (int)(parentY - sizeY) / 2);
|
||||
RenderWindow.Size = new((uint)sizeX, (uint)sizeY);
|
||||
|
||||
// 将 view 的大小设置成于 resolution 相同的大小, 其余属性都不变
|
||||
var view = RenderWindow.GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
view.Size = new(value.Width * signX, value.Height * signY);
|
||||
RenderWindow.SetView(view);
|
||||
|
||||
resolution = value;
|
||||
}
|
||||
}
|
||||
private Size resolution = new(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// 画面中心点
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public PointF Center
|
||||
{
|
||||
get
|
||||
{
|
||||
var center = RenderWindow.GetView().Center;
|
||||
return new(center.X, center.Y);
|
||||
}
|
||||
set
|
||||
{
|
||||
var view = RenderWindow.GetView();
|
||||
view.Center = new(value.X, value.Y);
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画面缩放
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public float Zoom
|
||||
{
|
||||
get => resolution.Width / Math.Abs(RenderWindow.GetView().Size.X);
|
||||
set
|
||||
{
|
||||
value = Math.Clamp(value, ZOOM_MIN, ZOOM_MAX);
|
||||
var view = RenderWindow.GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
view.Size = new(resolution.Width / value * signX, resolution.Height / value * signY);
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画面旋转
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public float Rotation
|
||||
{
|
||||
get => RenderWindow.GetView().Rotation;
|
||||
set
|
||||
{
|
||||
var view = RenderWindow.GetView();
|
||||
view.Rotation = value;
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 水平翻转
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool FlipX
|
||||
{
|
||||
get => RenderWindow.GetView().Size.X < 0;
|
||||
set
|
||||
{
|
||||
var view = RenderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.X > 0 && value || size.X < 0 && !value)
|
||||
size.X *= -1;
|
||||
view.Size = size;
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 垂直翻转
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool FlipY
|
||||
{
|
||||
get => RenderWindow.GetView().Size.Y < 0;
|
||||
set
|
||||
{
|
||||
var view = RenderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.Y > 0 && value || size.Y < 0 && !value)
|
||||
size.Y *= -1;
|
||||
view.Size = size;
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅渲染选中
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool RenderSelectedOnly { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 显示坐标轴
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool ShowAxis { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 最大帧率
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public uint MaxFps { get => maxFps; set { RenderWindow.SetFramerateLimit(value); maxFps = value; } }
|
||||
private uint maxFps = 60;
|
||||
|
||||
public SpinePreviewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
RenderWindow = new(panel.Handle);
|
||||
RenderWindow.SetActive(false);
|
||||
|
||||
// 设置默认参数
|
||||
Resolution = new(2048, 2048);
|
||||
Center = new(0, 0);
|
||||
FlipY = true;
|
||||
MaxFps = 30;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面帧参数
|
||||
/// </summary>
|
||||
public SpinePreviewerFrameArgs GetFrameArgs() => new(Resolution, RenderWindow.GetView(), RenderSelectedOnly);
|
||||
|
||||
/// <summary>
|
||||
/// 开始预览
|
||||
/// </summary>
|
||||
public void StartPreview()
|
||||
{
|
||||
if (task is not null)
|
||||
return;
|
||||
cancelToken = new();
|
||||
task = Task.Run(RenderTask, cancelToken.Token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止预览
|
||||
/// </summary>
|
||||
public void StopPreview()
|
||||
{
|
||||
if (task is null || cancelToken is null)
|
||||
return;
|
||||
cancelToken.Cancel();
|
||||
task.Wait();
|
||||
cancelToken = null;
|
||||
task = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 渲染任务
|
||||
/// </summary>
|
||||
private void RenderTask()
|
||||
{
|
||||
try
|
||||
{
|
||||
RenderWindow.SetActive(true);
|
||||
|
||||
float delta;
|
||||
while (cancelToken is not null && !cancelToken.IsCancellationRequested)
|
||||
{
|
||||
delta = Clock.ElapsedTime.AsSeconds();
|
||||
Clock.Restart();
|
||||
|
||||
RenderWindow.Clear(BackgroundColor);
|
||||
|
||||
if (ShowAxis)
|
||||
{
|
||||
// 画一个很长的坐标轴, 用 1e9 比较合适
|
||||
AxisVertex[0] = new(new(-1e9f, 0), AxisColor);
|
||||
AxisVertex[1] = new(new(1e9f, 0), AxisColor);
|
||||
RenderWindow.Draw(AxisVertex);
|
||||
AxisVertex[0] = new(new(0, -1e9f), AxisColor);
|
||||
AxisVertex[1] = new(new(0, 1e9f), AxisColor);
|
||||
RenderWindow.Draw(AxisVertex);
|
||||
}
|
||||
|
||||
// 渲染 Spine
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines;
|
||||
for (int i = spines.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (cancelToken is not null && cancelToken.IsCancellationRequested)
|
||||
break; // 提前中止
|
||||
|
||||
var spine = spines[i];
|
||||
spine.Update(delta);
|
||||
|
||||
if (RenderSelectedOnly && !spine.IsSelected)
|
||||
continue;
|
||||
|
||||
spine.IsDebug = true;
|
||||
RenderWindow.Draw(spine);
|
||||
spine.IsDebug = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderWindow.Display();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderWindow.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SpinePreviewer_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (RenderWindow is null)
|
||||
return;
|
||||
|
||||
float parentX = Width;
|
||||
float parentY = Height;
|
||||
float sizeX = panel.Width;
|
||||
float sizeY = panel.Height;
|
||||
|
||||
if ((sizeY / sizeX) < (parentY / parentX))
|
||||
{
|
||||
// 相同的 X, 子窗口 Y 更小
|
||||
sizeY = parentX * sizeY / sizeX;
|
||||
sizeX = parentX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 相同的 Y, 子窗口 X 更小
|
||||
sizeX = parentY * sizeX / sizeY;
|
||||
sizeY = parentY;
|
||||
}
|
||||
|
||||
// 必须通过 SFML 的方法调整窗口
|
||||
RenderWindow.Position = new((int)(parentX - sizeX) / 2, (int)(parentY - sizeY) / 2);
|
||||
RenderWindow.Size = new((uint)sizeX, (uint)sizeY);
|
||||
}
|
||||
|
||||
private void panel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
// 右键优先级高, 进入画面拖动模式, 需要重新记录源点
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
draggingSrc = RenderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
Cursor = Cursors.Hand;
|
||||
}
|
||||
// 按下了左键并且右键是松开的
|
||||
else if ((e.Button & MouseButtons.Left) != 0 && (MouseButtons & MouseButtons.Right) == 0)
|
||||
{
|
||||
draggingSrc = RenderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
var src = new PointF(((SFML.System.Vector2f)draggingSrc).X, ((SFML.System.Vector2f)draggingSrc).Y);
|
||||
|
||||
if (SpineListView is null)
|
||||
return;
|
||||
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines;
|
||||
|
||||
// 仅渲染选中模式禁止在画面里选择对象
|
||||
if (RenderSelectedOnly)
|
||||
{
|
||||
bool hit = false;
|
||||
foreach (int i in SpineListView.SelectedIndices)
|
||||
{
|
||||
if (!spines[i].Bounds.Contains(src)) continue;
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果没点到被选中的模型, 则不允许拖动
|
||||
if (!hit) draggingSrc = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 没有按下 Ctrl 键就只选中点击的那个, 所以先清空选中列表
|
||||
if ((ModifierKeys & Keys.Control) == 0)
|
||||
{
|
||||
bool hit = false;
|
||||
for (int i = 0; i < spines.Count; i++)
|
||||
{
|
||||
if (!spines[i].Bounds.Contains(src)) continue;
|
||||
|
||||
hit = true;
|
||||
|
||||
// 如果点到了没被选中的东西, 则清空原先选中的, 改为只选中这一次点的
|
||||
if (!SpineListView.SelectedIndices.Contains(i))
|
||||
{
|
||||
SpineListView.SelectedIndices.Clear();
|
||||
SpineListView.SelectedIndices.Add(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果点了空白的地方, 就清空选中列表
|
||||
if (!hit) SpineListView.SelectedIndices.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < spines.Count; i++)
|
||||
{
|
||||
if (!spines[i].Bounds.Contains(src))
|
||||
continue;
|
||||
|
||||
SpineListView.SelectedIndices.Add(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (draggingSrc is null)
|
||||
return;
|
||||
|
||||
var src = (SFML.System.Vector2f)draggingSrc;
|
||||
var dst = RenderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
var _delta = dst - src;
|
||||
var delta = new SizeF(_delta.X, _delta.Y);
|
||||
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
Center -= delta;
|
||||
}
|
||||
else if ((e.Button & MouseButtons.Left) != 0)
|
||||
{
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
foreach (int i in SpineListView.SelectedIndices)
|
||||
SpineListView.Spines[i].Position += delta;
|
||||
}
|
||||
}
|
||||
draggingSrc = dst;
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
// 右键高优先级, 结束画面拖动模式
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
SpineListView?.PropertyGrid?.Refresh();
|
||||
|
||||
draggingSrc = null;
|
||||
Cursor = Cursors.Default;
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
// 按下了左键并且右键是松开的
|
||||
else if ((e.Button & MouseButtons.Left) != 0 && (MouseButtons & MouseButtons.Right) == 0)
|
||||
{
|
||||
draggingSrc = null;
|
||||
SpineListView?.PropertyGrid?.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
Zoom *= (e.Delta > 0 ? 1.1f : 0.9f);
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面帧参数
|
||||
/// </summary>
|
||||
public class SpinePreviewerFrameArgs(Size resolution, SFML.Graphics.View view, bool renderSelectedOnly)
|
||||
{
|
||||
/// <summary>
|
||||
/// 分辨率
|
||||
/// </summary>
|
||||
public Size Resolution => resolution;
|
||||
|
||||
/// <summary>
|
||||
/// 渲染视窗
|
||||
/// </summary>
|
||||
public SFML.Graphics.View View => view;
|
||||
|
||||
/// <summary>
|
||||
/// 是否仅渲染/导出选中骨骼
|
||||
/// </summary>
|
||||
public bool RenderSelectedOnly => renderSelectedOnly;
|
||||
}
|
||||
|
||||
}
|
||||
255
SpineViewer/Controls/SpineViewPropertyGrid.Designer.cs
generated
Normal file
255
SpineViewer/Controls/SpineViewPropertyGrid.Designer.cs
generated
Normal file
@@ -0,0 +1,255 @@
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
partial class SpineViewPropertyGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 组件设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpineViewPropertyGrid));
|
||||
tabControl = new TabControl();
|
||||
tabPage_BaseInfo = new TabPage();
|
||||
propertyGrid_BaseInfo = new PropertyGrid();
|
||||
tabPage_Render = new TabPage();
|
||||
propertyGrid_Render = new PropertyGrid();
|
||||
tabPage_Transform = new TabPage();
|
||||
propertyGrid_Transform = new PropertyGrid();
|
||||
tabPage_Skin = new TabPage();
|
||||
propertyGrid_Skin = new PropertyGrid();
|
||||
contextMenuStrip_Skin = new ContextMenuStrip(components);
|
||||
toolStripMenuItem_ReloadSkins = new ToolStripMenuItem();
|
||||
tabPage_Slot = new TabPage();
|
||||
propertyGrid_Slot = new PropertyGrid();
|
||||
tabPage_Animation = new TabPage();
|
||||
propertyGrid_Animation = new PropertyGrid();
|
||||
contextMenuStrip_Animation = new ContextMenuStrip(components);
|
||||
toolStripMenuItem_AddAnimation = new ToolStripMenuItem();
|
||||
toolStripMenuItem_RemoveAnimation = new ToolStripMenuItem();
|
||||
tabPage_Debug = new TabPage();
|
||||
propertyGrid_Debug = new PropertyGrid();
|
||||
tabControl.SuspendLayout();
|
||||
tabPage_BaseInfo.SuspendLayout();
|
||||
tabPage_Render.SuspendLayout();
|
||||
tabPage_Transform.SuspendLayout();
|
||||
tabPage_Skin.SuspendLayout();
|
||||
contextMenuStrip_Skin.SuspendLayout();
|
||||
tabPage_Slot.SuspendLayout();
|
||||
tabPage_Animation.SuspendLayout();
|
||||
contextMenuStrip_Animation.SuspendLayout();
|
||||
tabPage_Debug.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// tabControl
|
||||
//
|
||||
resources.ApplyResources(tabControl, "tabControl");
|
||||
tabControl.Controls.Add(tabPage_BaseInfo);
|
||||
tabControl.Controls.Add(tabPage_Render);
|
||||
tabControl.Controls.Add(tabPage_Transform);
|
||||
tabControl.Controls.Add(tabPage_Skin);
|
||||
tabControl.Controls.Add(tabPage_Slot);
|
||||
tabControl.Controls.Add(tabPage_Animation);
|
||||
tabControl.Controls.Add(tabPage_Debug);
|
||||
tabControl.Multiline = true;
|
||||
tabControl.Name = "tabControl";
|
||||
tabControl.SelectedIndex = 0;
|
||||
tabControl.SizeMode = TabSizeMode.FillToRight;
|
||||
//
|
||||
// tabPage_BaseInfo
|
||||
//
|
||||
resources.ApplyResources(tabPage_BaseInfo, "tabPage_BaseInfo");
|
||||
tabPage_BaseInfo.BackColor = SystemColors.Control;
|
||||
tabPage_BaseInfo.Controls.Add(propertyGrid_BaseInfo);
|
||||
tabPage_BaseInfo.Name = "tabPage_BaseInfo";
|
||||
//
|
||||
// propertyGrid_BaseInfo
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_BaseInfo, "propertyGrid_BaseInfo");
|
||||
propertyGrid_BaseInfo.Name = "propertyGrid_BaseInfo";
|
||||
propertyGrid_BaseInfo.PropertySort = PropertySort.Alphabetical;
|
||||
propertyGrid_BaseInfo.ToolbarVisible = false;
|
||||
//
|
||||
// tabPage_Render
|
||||
//
|
||||
resources.ApplyResources(tabPage_Render, "tabPage_Render");
|
||||
tabPage_Render.BackColor = SystemColors.Control;
|
||||
tabPage_Render.Controls.Add(propertyGrid_Render);
|
||||
tabPage_Render.Name = "tabPage_Render";
|
||||
//
|
||||
// propertyGrid_Render
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Render, "propertyGrid_Render");
|
||||
propertyGrid_Render.Name = "propertyGrid_Render";
|
||||
propertyGrid_Render.PropertySort = PropertySort.Alphabetical;
|
||||
propertyGrid_Render.ToolbarVisible = false;
|
||||
//
|
||||
// tabPage_Transform
|
||||
//
|
||||
resources.ApplyResources(tabPage_Transform, "tabPage_Transform");
|
||||
tabPage_Transform.BackColor = SystemColors.Control;
|
||||
tabPage_Transform.Controls.Add(propertyGrid_Transform);
|
||||
tabPage_Transform.Name = "tabPage_Transform";
|
||||
//
|
||||
// propertyGrid_Transform
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Transform, "propertyGrid_Transform");
|
||||
propertyGrid_Transform.Name = "propertyGrid_Transform";
|
||||
propertyGrid_Transform.PropertySort = PropertySort.Alphabetical;
|
||||
propertyGrid_Transform.ToolbarVisible = false;
|
||||
//
|
||||
// tabPage_Skin
|
||||
//
|
||||
resources.ApplyResources(tabPage_Skin, "tabPage_Skin");
|
||||
tabPage_Skin.BackColor = SystemColors.Control;
|
||||
tabPage_Skin.Controls.Add(propertyGrid_Skin);
|
||||
tabPage_Skin.Name = "tabPage_Skin";
|
||||
//
|
||||
// propertyGrid_Skin
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Skin, "propertyGrid_Skin");
|
||||
propertyGrid_Skin.ContextMenuStrip = contextMenuStrip_Skin;
|
||||
propertyGrid_Skin.Name = "propertyGrid_Skin";
|
||||
propertyGrid_Skin.PropertySort = PropertySort.NoSort;
|
||||
propertyGrid_Skin.ToolbarVisible = false;
|
||||
//
|
||||
// contextMenuStrip_Skin
|
||||
//
|
||||
resources.ApplyResources(contextMenuStrip_Skin, "contextMenuStrip_Skin");
|
||||
contextMenuStrip_Skin.ImageScalingSize = new Size(24, 24);
|
||||
contextMenuStrip_Skin.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_ReloadSkins });
|
||||
contextMenuStrip_Skin.Name = "contextMenuStrip1";
|
||||
//
|
||||
// toolStripMenuItem_ReloadSkins
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ReloadSkins, "toolStripMenuItem_ReloadSkins");
|
||||
toolStripMenuItem_ReloadSkins.Name = "toolStripMenuItem_ReloadSkins";
|
||||
toolStripMenuItem_ReloadSkins.Click += toolStripMenuItem_ReloadSkins_Click;
|
||||
//
|
||||
// tabPage_Slot
|
||||
//
|
||||
resources.ApplyResources(tabPage_Slot, "tabPage_Slot");
|
||||
tabPage_Slot.BackColor = SystemColors.Control;
|
||||
tabPage_Slot.Controls.Add(propertyGrid_Slot);
|
||||
tabPage_Slot.Name = "tabPage_Slot";
|
||||
//
|
||||
// propertyGrid_Slot
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Slot, "propertyGrid_Slot");
|
||||
propertyGrid_Slot.Name = "propertyGrid_Slot";
|
||||
propertyGrid_Slot.PropertySort = PropertySort.Alphabetical;
|
||||
propertyGrid_Slot.ToolbarVisible = false;
|
||||
//
|
||||
// tabPage_Animation
|
||||
//
|
||||
resources.ApplyResources(tabPage_Animation, "tabPage_Animation");
|
||||
tabPage_Animation.BackColor = SystemColors.Control;
|
||||
tabPage_Animation.Controls.Add(propertyGrid_Animation);
|
||||
tabPage_Animation.Name = "tabPage_Animation";
|
||||
//
|
||||
// propertyGrid_Animation
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Animation, "propertyGrid_Animation");
|
||||
propertyGrid_Animation.ContextMenuStrip = contextMenuStrip_Animation;
|
||||
propertyGrid_Animation.Name = "propertyGrid_Animation";
|
||||
propertyGrid_Animation.PropertySort = PropertySort.NoSort;
|
||||
propertyGrid_Animation.ToolbarVisible = false;
|
||||
//
|
||||
// contextMenuStrip_Animation
|
||||
//
|
||||
resources.ApplyResources(contextMenuStrip_Animation, "contextMenuStrip_Animation");
|
||||
contextMenuStrip_Animation.ImageScalingSize = new Size(24, 24);
|
||||
contextMenuStrip_Animation.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_AddAnimation, toolStripMenuItem_RemoveAnimation });
|
||||
contextMenuStrip_Animation.Name = "contextMenuStrip1";
|
||||
contextMenuStrip_Animation.Opening += contextMenuStrip_Animation_Opening;
|
||||
//
|
||||
// toolStripMenuItem_AddAnimation
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_AddAnimation, "toolStripMenuItem_AddAnimation");
|
||||
toolStripMenuItem_AddAnimation.Name = "toolStripMenuItem_AddAnimation";
|
||||
toolStripMenuItem_AddAnimation.Click += toolStripMenuItem_AddAnimation_Click;
|
||||
//
|
||||
// toolStripMenuItem_RemoveAnimation
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_RemoveAnimation, "toolStripMenuItem_RemoveAnimation");
|
||||
toolStripMenuItem_RemoveAnimation.Name = "toolStripMenuItem_RemoveAnimation";
|
||||
toolStripMenuItem_RemoveAnimation.Click += toolStripMenuItem_RemoveAnimation_Click;
|
||||
//
|
||||
// tabPage_Debug
|
||||
//
|
||||
resources.ApplyResources(tabPage_Debug, "tabPage_Debug");
|
||||
tabPage_Debug.BackColor = SystemColors.Control;
|
||||
tabPage_Debug.Controls.Add(propertyGrid_Debug);
|
||||
tabPage_Debug.Name = "tabPage_Debug";
|
||||
//
|
||||
// propertyGrid_Debug
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Debug, "propertyGrid_Debug");
|
||||
propertyGrid_Debug.Name = "propertyGrid_Debug";
|
||||
propertyGrid_Debug.PropertySort = PropertySort.NoSort;
|
||||
propertyGrid_Debug.ToolbarVisible = false;
|
||||
//
|
||||
// SpineViewPropertyGrid
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(tabControl);
|
||||
Name = "SpineViewPropertyGrid";
|
||||
tabControl.ResumeLayout(false);
|
||||
tabPage_BaseInfo.ResumeLayout(false);
|
||||
tabPage_Render.ResumeLayout(false);
|
||||
tabPage_Transform.ResumeLayout(false);
|
||||
tabPage_Skin.ResumeLayout(false);
|
||||
contextMenuStrip_Skin.ResumeLayout(false);
|
||||
tabPage_Slot.ResumeLayout(false);
|
||||
tabPage_Animation.ResumeLayout(false);
|
||||
contextMenuStrip_Animation.ResumeLayout(false);
|
||||
tabPage_Debug.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private TabControl tabControl;
|
||||
private TabPage tabPage_BaseInfo;
|
||||
private TabPage tabPage_Render;
|
||||
private TabPage tabPage_Transform;
|
||||
private TabPage tabPage_Skin;
|
||||
private TabPage tabPage_Animation;
|
||||
private PropertyGrid propertyGrid_BaseInfo;
|
||||
private PropertyGrid propertyGrid_Render;
|
||||
private PropertyGrid propertyGrid_Transform;
|
||||
private PropertyGrid propertyGrid_Skin;
|
||||
private PropertyGrid propertyGrid_Animation;
|
||||
private ContextMenuStrip contextMenuStrip_Skin;
|
||||
private ContextMenuStrip contextMenuStrip_Animation;
|
||||
private ToolStripMenuItem toolStripMenuItem_ReloadSkins;
|
||||
private ToolStripMenuItem toolStripMenuItem_AddAnimation;
|
||||
private ToolStripMenuItem toolStripMenuItem_RemoveAnimation;
|
||||
private TabPage tabPage_Debug;
|
||||
private PropertyGrid propertyGrid_Debug;
|
||||
private TabPage tabPage_Slot;
|
||||
private PropertyGrid propertyGrid_Slot;
|
||||
}
|
||||
}
|
||||
107
SpineViewer/Controls/SpineViewPropertyGrid.cs
Normal file
107
SpineViewer/Controls/SpineViewPropertyGrid.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using SpineViewer.Utils;
|
||||
using SpineViewer.Spine.SpineView;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
public partial class SpineViewPropertyGrid : UserControl
|
||||
{
|
||||
public SpineViewPropertyGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置选中的对象列表, 可以赋值 null 来清空选中, 行为与 PropertyGrid.SelectedObjects 类似
|
||||
/// </summary>
|
||||
public SpineObjectProperty[] SelectedSpines
|
||||
{
|
||||
get => selectedSpines ?? [];
|
||||
set
|
||||
{
|
||||
if (value is null || value.Length <= 0)
|
||||
{
|
||||
selectedSpines = null;
|
||||
propertyGrid_BaseInfo.SelectedObject = null;
|
||||
propertyGrid_Render.SelectedObject = null;
|
||||
propertyGrid_Transform.SelectedObject = null;
|
||||
propertyGrid_Skin.SelectedObject = null;
|
||||
propertyGrid_Slot.SelectedObject = null;
|
||||
propertyGrid_Animation.SelectedObject = null;
|
||||
propertyGrid_Debug.SelectedObject = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedSpines = value;
|
||||
propertyGrid_BaseInfo.SelectedObjects = value.Select(e => e.BaseInfo).ToArray();
|
||||
propertyGrid_Render.SelectedObjects = value.Select(e => e.Render).ToArray();
|
||||
propertyGrid_Transform.SelectedObjects = value.Select(e => e.Transform).ToArray();
|
||||
propertyGrid_Skin.SelectedObjects = value.Select(e => e.Skin).ToArray();
|
||||
propertyGrid_Slot.SelectedObjects = value.Select(e => e.Slot).ToArray();
|
||||
propertyGrid_Animation.SelectedObjects = value.Select(e => e.Animation).ToArray();
|
||||
propertyGrid_Debug.SelectedObjects = value.Select(e => e.Debug).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
private SpineObjectProperty[]? selectedSpines = null;
|
||||
|
||||
private void contextMenuStrip_Animation_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
if (selectedSpines?.Length == 1)
|
||||
{
|
||||
toolStripMenuItem_AddAnimation.Enabled = true;
|
||||
toolStripMenuItem_RemoveAnimation.Enabled = propertyGrid_Animation.SelectedGridItem.Value is TrackAnimationProperty;
|
||||
}
|
||||
else
|
||||
{
|
||||
toolStripMenuItem_AddAnimation.Enabled = false;
|
||||
toolStripMenuItem_RemoveAnimation.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ReloadSkins_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var sp in selectedSpines)
|
||||
sp.Spine.ReloadSkins();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_AddAnimation_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (selectedSpines?.Length != 1) return;
|
||||
|
||||
var spine = selectedSpines[0].Animation.Spine;
|
||||
spine.SetAnimation(spine.GetTrackIndices().Max() + 1, spine.AnimationNames[0]);
|
||||
propertyGrid_Animation.Refresh();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_RemoveAnimation_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (selectedSpines?.Length != 1) return;
|
||||
|
||||
if (propertyGrid_Animation.SelectedGridItem.Value is TrackAnimationProperty wrapper)
|
||||
{
|
||||
selectedSpines[0].Animation.Spine.ClearTrack(wrapper.Index);
|
||||
propertyGrid_Animation.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Refresh()
|
||||
{
|
||||
base.Refresh();
|
||||
propertyGrid_BaseInfo.Refresh();
|
||||
propertyGrid_Render.Refresh();
|
||||
propertyGrid_Transform.Refresh();
|
||||
propertyGrid_Skin.Refresh();
|
||||
propertyGrid_Animation.Refresh();
|
||||
propertyGrid_Debug.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
164
SpineViewer/Controls/SpineViewPropertyGrid.en.resx
Normal file
164
SpineViewer/Controls/SpineViewPropertyGrid.en.resx
Normal file
@@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="tabPage_Animation.Text" xml:space="preserve">
|
||||
<value>Animation</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAnimation.Text" xml:space="preserve">
|
||||
<value>Remove</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Text" xml:space="preserve">
|
||||
<value>Render</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.Text" xml:space="preserve">
|
||||
<value>Slot</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Text" xml:space="preserve">
|
||||
<value>Skin</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="tabPage_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 330</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Text" xml:space="preserve">
|
||||
<value>Transform</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 330</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Text" xml:space="preserve">
|
||||
<value>Debug</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ReloadSkins.Text" xml:space="preserve">
|
||||
<value>Reload skin</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 330</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="toolStripMenuItem_RemoveAnimation.Size" type="System.Resources.ResXNullRef, System.Windows.Forms">
|
||||
<value />
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 330</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Text" xml:space="preserve">
|
||||
<value>Basic Information</value>
|
||||
</data>
|
||||
</root>
|
||||
637
SpineViewer/Controls/SpineViewPropertyGrid.resx
Normal file
637
SpineViewer/Controls/SpineViewPropertyGrid.resx
Normal file
@@ -0,0 +1,637 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="propertyGrid_Slot.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="tabControl.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Animation.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip_Skin.Name" xml:space="preserve">
|
||||
<value>contextMenuStrip_Skin</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Animation.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Animation</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="tabPage_Slot.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip_Skin.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>170, 28</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Skin.Name" xml:space="preserve">
|
||||
<value>tabPage_Skin</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Debug.Name" xml:space="preserve">
|
||||
<value>tabPage_Debug</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_BaseInfo.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Transform.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tabPage_BaseInfo.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Render.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabControl.ItemSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>90, 35</value>
|
||||
</data>
|
||||
<data name="tabControl.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>271, 373</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="propertyGrid_Debug.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.Text" xml:space="preserve">
|
||||
<value>动画</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Animation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_BaseInfo.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tabControl.Name" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>tabControl.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip_Animation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>109, 52</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip_Animation.Name" xml:space="preserve">
|
||||
<value>contextMenuStrip_Animation</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_RemoveAnimation.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_RemoveAnimation</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Debug.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>271, 373</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Debug.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Debug</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_BaseInfo.Name" xml:space="preserve">
|
||||
<value>propertyGrid_BaseInfo</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Transform.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Transform</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAnimation.Text" xml:space="preserve">
|
||||
<value>移除</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Skin.Parent" xml:space="preserve">
|
||||
<value>tabPage_Skin</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ReloadSkins.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Render.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tabControl.Alignment" type="System.Windows.Forms.TabAlignment, System.Windows.Forms">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip_Skin.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Transform.Name" xml:space="preserve">
|
||||
<value>tabPage_Transform</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Render.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Render.Name" xml:space="preserve">
|
||||
<value>tabPage_Render</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Slot.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>tabPage_BaseInfo.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Text" xml:space="preserve">
|
||||
<value>渲染</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_AddAnimation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.Text" xml:space="preserve">
|
||||
<value>插槽</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Render.Parent" xml:space="preserve">
|
||||
<value>tabPage_Render</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Text" xml:space="preserve">
|
||||
<value>皮肤</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Skin.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Slot.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tabControl.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Slot.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabControl.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name=">>tabControl.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Skin.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Debug.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Skin.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Skin.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Text" xml:space="preserve">
|
||||
<value>变换</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Slot.Parent" xml:space="preserve">
|
||||
<value>tabPage_Slot</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Transform.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Render.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>tabPage_BaseInfo.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddAnimation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>108, 24</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Slot.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Skin.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Animation.Name" xml:space="preserve">
|
||||
<value>tabPage_Animation</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Transform.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabControl.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddAnimation.Text" xml:space="preserve">
|
||||
<value>添加</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ReloadSkins.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>169, 24</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Text" xml:space="preserve">
|
||||
<value>调试</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Animation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ReloadSkins.Text" xml:space="preserve">
|
||||
<value>重新加载皮肤</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Slot.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Slot</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tabPage_BaseInfo.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>SpineViewPropertyGrid</value>
|
||||
</data>
|
||||
<data name=">>tabControl.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip_Animation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Debug.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Slot.Name" xml:space="preserve">
|
||||
<value>tabPage_Slot</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Animation.Parent" xml:space="preserve">
|
||||
<value>tabPage_Animation</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>tabPage_BaseInfo.Name" xml:space="preserve">
|
||||
<value>tabPage_BaseInfo</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_BaseInfo.Parent" xml:space="preserve">
|
||||
<value>tabPage_BaseInfo</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Transform.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Debug.Parent" xml:space="preserve">
|
||||
<value>tabPage_Debug</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Transform.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Slot.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabControl.Padding" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAnimation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>108, 24</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Debug.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Transform.Parent" xml:space="preserve">
|
||||
<value>tabPage_Transform</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_AddAnimation.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_AddAnimation</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Animation.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Render.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Render</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Debug.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Animation.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Render.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ReloadSkins.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_ReloadSkins</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Skin.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Skin</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_RemoveAnimation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Text" xml:space="preserve">
|
||||
<value>基本信息</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip_Skin.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>29, 26</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip_Animation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>318, 25</value>
|
||||
</metadata>
|
||||
</root>
|
||||
194
SpineViewer/Dialogs/AboutDialog.Designer.cs
generated
194
SpineViewer/Dialogs/AboutDialog.Designer.cs
generated
@@ -19,130 +19,82 @@
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows 窗体设计器生成的代码
|
||||
#region Windows 窗体设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutDialog));
|
||||
tableLayoutPanel_About = new TableLayoutPanel();
|
||||
label3 = new Label();
|
||||
label1 = new Label();
|
||||
label_Version = new Label();
|
||||
linkLabel_RepoUrl = new LinkLabel();
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel_About.SuspendLayout();
|
||||
panel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel_About
|
||||
//
|
||||
tableLayoutPanel_About.BackColor = Color.Transparent;
|
||||
tableLayoutPanel_About.ColumnCount = 2;
|
||||
tableLayoutPanel_About.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 28.5714283F));
|
||||
tableLayoutPanel_About.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 71.42857F));
|
||||
tableLayoutPanel_About.Controls.Add(label3, 0, 1);
|
||||
tableLayoutPanel_About.Controls.Add(label1, 0, 0);
|
||||
tableLayoutPanel_About.Controls.Add(label_Version, 1, 0);
|
||||
tableLayoutPanel_About.Controls.Add(linkLabel_RepoUrl, 1, 1);
|
||||
tableLayoutPanel_About.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel_About.Location = new Point(50, 15);
|
||||
tableLayoutPanel_About.Margin = new Padding(0);
|
||||
tableLayoutPanel_About.Name = "tableLayoutPanel_About";
|
||||
tableLayoutPanel_About.RowCount = 3;
|
||||
tableLayoutPanel_About.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel_About.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel_About.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel_About.Size = new Size(604, 254);
|
||||
tableLayoutPanel_About.TabIndex = 1;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.AutoSize = true;
|
||||
label3.Dock = DockStyle.Fill;
|
||||
label3.Location = new Point(3, 54);
|
||||
label3.Margin = new Padding(3, 10, 3, 10);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new Size(166, 24);
|
||||
label3.TabIndex = 2;
|
||||
label3.Text = "项目地址:";
|
||||
label3.TextAlign = ContentAlignment.MiddleRight;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Dock = DockStyle.Fill;
|
||||
label1.Location = new Point(3, 10);
|
||||
label1.Margin = new Padding(3, 10, 3, 10);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(166, 24);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "程序版本:";
|
||||
label1.TextAlign = ContentAlignment.MiddleRight;
|
||||
//
|
||||
// label_Version
|
||||
//
|
||||
label_Version.Anchor = AnchorStyles.Left;
|
||||
label_Version.AutoSize = true;
|
||||
label_Version.Location = new Point(175, 10);
|
||||
label_Version.Name = "label_Version";
|
||||
label_Version.Size = new Size(61, 24);
|
||||
label_Version.TabIndex = 1;
|
||||
label_Version.Text = "vX.Y.Z";
|
||||
label_Version.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// linkLabel_RepoUrl
|
||||
//
|
||||
linkLabel_RepoUrl.Anchor = AnchorStyles.Left;
|
||||
linkLabel_RepoUrl.AutoSize = true;
|
||||
linkLabel_RepoUrl.Location = new Point(175, 54);
|
||||
linkLabel_RepoUrl.Name = "linkLabel_RepoUrl";
|
||||
linkLabel_RepoUrl.Size = new Size(356, 24);
|
||||
linkLabel_RepoUrl.TabIndex = 3;
|
||||
linkLabel_RepoUrl.TabStop = true;
|
||||
linkLabel_RepoUrl.Text = "https://github.com/ww-rm/SpineViewer";
|
||||
linkLabel_RepoUrl.LinkClicked += linkLabel_RepoUrl_LinkClicked;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.BackgroundImageLayout = ImageLayout.Center;
|
||||
panel1.Controls.Add(tableLayoutPanel_About);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(16, 17);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(50, 15, 50, 10);
|
||||
panel1.Size = new Size(704, 279);
|
||||
panel1.TabIndex = 2;
|
||||
//
|
||||
// AboutDialog
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(736, 313);
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
Margin = new Padding(6);
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "AboutDialog";
|
||||
Padding = new Padding(16, 17, 16, 17);
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
Text = "关于 SpineViewer";
|
||||
tableLayoutPanel_About.ResumeLayout(false);
|
||||
tableLayoutPanel_About.PerformLayout();
|
||||
panel1.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutDialog));
|
||||
tableLayoutPanel_About = new TableLayoutPanel();
|
||||
label3 = new Label();
|
||||
label1 = new Label();
|
||||
label_Version = new Label();
|
||||
linkLabel_RepoUrl = new LinkLabel();
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel_About.SuspendLayout();
|
||||
panel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel_About
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel_About, "tableLayoutPanel_About");
|
||||
tableLayoutPanel_About.BackColor = Color.Transparent;
|
||||
tableLayoutPanel_About.Controls.Add(label3, 0, 1);
|
||||
tableLayoutPanel_About.Controls.Add(label1, 0, 0);
|
||||
tableLayoutPanel_About.Controls.Add(label_Version, 1, 0);
|
||||
tableLayoutPanel_About.Controls.Add(linkLabel_RepoUrl, 1, 1);
|
||||
tableLayoutPanel_About.Name = "tableLayoutPanel_About";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(label3, "label3");
|
||||
label3.Name = "label3";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
resources.ApplyResources(label1, "label1");
|
||||
label1.Name = "label1";
|
||||
//
|
||||
// label_Version
|
||||
//
|
||||
resources.ApplyResources(label_Version, "label_Version");
|
||||
label_Version.Name = "label_Version";
|
||||
//
|
||||
// linkLabel_RepoUrl
|
||||
//
|
||||
resources.ApplyResources(linkLabel_RepoUrl, "linkLabel_RepoUrl");
|
||||
linkLabel_RepoUrl.Name = "linkLabel_RepoUrl";
|
||||
linkLabel_RepoUrl.TabStop = true;
|
||||
linkLabel_RepoUrl.LinkClicked += linkLabel_RepoUrl_LinkClicked;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel_About);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// AboutDialog
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "AboutDialog";
|
||||
ShowInTaskbar = false;
|
||||
tableLayoutPanel_About.ResumeLayout(false);
|
||||
tableLayoutPanel_About.PerformLayout();
|
||||
panel1.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
private TableLayoutPanel tableLayoutPanel_About;
|
||||
private TableLayoutPanel tableLayoutPanel_About;
|
||||
private Label label3;
|
||||
private Label label1;
|
||||
private Label label_Version;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
@@ -15,12 +16,20 @@ namespace SpineViewer.Dialogs
|
||||
public AboutDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
Text = $"关于 {Program.Name}";
|
||||
Text = $"{Properties.Resources.about} {ProgramName}";
|
||||
label_Version.Text = $"v{InformationalVersion}";
|
||||
}
|
||||
|
||||
public string InformationalVersion =>
|
||||
Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
public string ProgramName => Process.GetCurrentProcess().ProcessName;
|
||||
|
||||
public string InformationalVersion
|
||||
=> Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
|
||||
public string ProgramUrl
|
||||
{
|
||||
get => linkLabel_RepoUrl.Text;
|
||||
set => linkLabel_RepoUrl.Text = value;
|
||||
}
|
||||
|
||||
private void linkLabel_RepoUrl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
@@ -32,7 +41,7 @@ namespace SpineViewer.Dialogs
|
||||
else
|
||||
{
|
||||
Clipboard.SetText(url);
|
||||
MessageBox.Info("链接已复制到剪贴板,请前往浏览器进行访问");
|
||||
MessagePopup.Info(Properties.Resources.notifyCopyGithubLink, Properties.Resources.msgBoxInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,9 +117,12 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="folderBrowserDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>Github link:</value>
|
||||
</data>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>Version:</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
@@ -3267,4 +3270,7 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>About SpineViewer</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,7 +117,82 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="label_Version.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name=">>label1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name="label3.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="label_Version.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="label_Version.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>48, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="label_Version.Text" xml:space="preserve">
|
||||
<value>vX.Y.Z</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>linkLabel_RepoUrl.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="linkLabel_RepoUrl.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name="label3.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleRight</value>
|
||||
</data>
|
||||
<data name="label3.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 8, 2, 8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.RowCount" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 8</value>
|
||||
</data>
|
||||
<data name=">>label3.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name=">>linkLabel_RepoUrl.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>36, 12</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>127, 44</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>AboutDialog</value>
|
||||
</data>
|
||||
<data name=">>label3.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>关于 SpineViewer</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3264,4 +3339,169 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="label1.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleRight</value>
|
||||
</data>
|
||||
<data name=">>label3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="label_Version.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleLeft</value>
|
||||
</data>
|
||||
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>121, 20</value>
|
||||
</data>
|
||||
<data name=">>panel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label_Version.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name=">>label1.Name" xml:space="preserve">
|
||||
<value>label1</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.Text" xml:space="preserve">
|
||||
<value>https://github.com/ww-rm/SpineViewer</value>
|
||||
</data>
|
||||
<data name=">>label3.Name" xml:space="preserve">
|
||||
<value>label3</value>
|
||||
</data>
|
||||
<data name=">>label_Version.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel_About.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>4, 5, 4, 5</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>panel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="label3.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>panel1.Name" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="label1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 8, 2, 8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label3" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label_Version" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="linkLabel_RepoUrl" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,28.571428,Percent,71.42857" /><Rows Styles="AutoSize,0,AutoSize,0,Percent,100" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>label_Version.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 44</value>
|
||||
</data>
|
||||
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>121, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>439, 213</value>
|
||||
</data>
|
||||
<data name="label_Version.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name=">>label1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel_About.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>label_Version.Name" xml:space="preserve">
|
||||
<value>label_Version</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>272, 20</value>
|
||||
</data>
|
||||
<data name=">>linkLabel_RepoUrl.Name" xml:space="preserve">
|
||||
<value>linkLabel_RepoUrl</value>
|
||||
</data>
|
||||
<data name="label_Version.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>127, 8</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 14</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel_About.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="label1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>panel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>511, 233</value>
|
||||
</data>
|
||||
<data name="$this.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>12, 14, 12, 14</value>
|
||||
</data>
|
||||
<data name=">>linkLabel_RepoUrl.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>程序版本:</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterParent</value>
|
||||
</data>
|
||||
<data name="panel1.BackgroundImageLayout" type="System.Windows.Forms.ImageLayout, System.Windows.Forms">
|
||||
<value>Center</value>
|
||||
</data>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>项目地址:</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel_About.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>535, 261</value>
|
||||
</data>
|
||||
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>36, 12, 36, 8</value>
|
||||
</data>
|
||||
<data name="label_Version.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>label1.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
268
SpineViewer/Dialogs/BatchOpenSpineDialog.Designer.cs
generated
268
SpineViewer/Dialogs/BatchOpenSpineDialog.Designer.cs
generated
@@ -20,171 +20,113 @@
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BatchOpenSpineDialog));
|
||||
panel = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label4 = new Label();
|
||||
label3 = new Label();
|
||||
comboBox_Version = new ComboBox();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
skelFileListBox = new SpineViewer.Controls.SkelFileListBox();
|
||||
panel.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel
|
||||
//
|
||||
panel.Controls.Add(tableLayoutPanel1);
|
||||
panel.Dock = DockStyle.Fill;
|
||||
panel.Location = new Point(0, 0);
|
||||
panel.Name = "panel";
|
||||
panel.Padding = new Padding(50, 15, 50, 10);
|
||||
panel.Size = new Size(1042, 472);
|
||||
panel.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.ColumnCount = 2;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_Version, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 3);
|
||||
tableLayoutPanel1.Controls.Add(skelFileListBox, 0, 1);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(50, 15);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 3;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(942, 447);
|
||||
tableLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.AutoSize = true;
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Dock = DockStyle.Fill;
|
||||
label4.Location = new Point(15, 15);
|
||||
label4.Margin = new Padding(15);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new Size(912, 24);
|
||||
label4.TabIndex = 14;
|
||||
label4.Text = "说明:批量导入只需要选择skel文件,atlas文件需要在同目录下并且与skel文件名相同";
|
||||
label4.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Anchor = AnchorStyles.Right;
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new Point(3, 343);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new Size(50, 24);
|
||||
label3.TabIndex = 12;
|
||||
label3.Text = "版本:";
|
||||
//
|
||||
// comboBox_Version
|
||||
//
|
||||
comboBox_Version.Anchor = AnchorStyles.Left;
|
||||
comboBox_Version.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_Version.FormattingEnabled = true;
|
||||
comboBox_Version.Location = new Point(59, 339);
|
||||
comboBox_Version.Name = "comboBox_Version";
|
||||
comboBox_Version.Size = new Size(182, 32);
|
||||
comboBox_Version.Sorted = true;
|
||||
comboBox_Version.TabIndex = 13;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
tableLayoutPanel2.AutoSize = true;
|
||||
tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
tableLayoutPanel2.ColumnCount = 2;
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel2.Location = new Point(3, 404);
|
||||
tableLayoutPanel2.Margin = new Padding(3, 30, 3, 3);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
tableLayoutPanel2.RowCount = 1;
|
||||
tableLayoutPanel2.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel2.Size = new Size(936, 40);
|
||||
tableLayoutPanel2.TabIndex = 11;
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
button_Ok.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
button_Ok.Location = new Point(326, 3);
|
||||
button_Ok.Margin = new Padding(3, 3, 30, 3);
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.Size = new Size(112, 34);
|
||||
button_Ok.TabIndex = 7;
|
||||
button_Ok.Text = "确认";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
button_Cancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
|
||||
button_Cancel.Location = new Point(498, 3);
|
||||
button_Cancel.Margin = new Padding(30, 3, 3, 3);
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.Size = new Size(112, 34);
|
||||
button_Cancel.TabIndex = 8;
|
||||
button_Cancel.Text = "取消";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// skelFileListBox
|
||||
//
|
||||
tableLayoutPanel1.SetColumnSpan(skelFileListBox, 2);
|
||||
skelFileListBox.Dock = DockStyle.Fill;
|
||||
skelFileListBox.Location = new Point(3, 57);
|
||||
skelFileListBox.Name = "skelFileListBox";
|
||||
skelFileListBox.Size = new Size(936, 276);
|
||||
skelFileListBox.TabIndex = 15;
|
||||
//
|
||||
// BatchOpenSpineDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
ClientSize = new Size(1042, 472);
|
||||
Controls.Add(panel);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "BatchOpenSpineDialog";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "批量打开骨骼";
|
||||
panel.ResumeLayout(false);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BatchOpenSpineDialog));
|
||||
panel = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label4 = new Label();
|
||||
label3 = new Label();
|
||||
comboBox_Version = new ComboBox();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
skelFileListBox = new Controls.SkelFileListBox();
|
||||
panel.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel
|
||||
//
|
||||
resources.ApplyResources(panel, "panel");
|
||||
panel.Controls.Add(tableLayoutPanel1);
|
||||
panel.Name = "panel";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_Version, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 3);
|
||||
tableLayoutPanel1.Controls.Add(skelFileListBox, 0, 1);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
resources.ApplyResources(label4, "label4");
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Name = "label4";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(label3, "label3");
|
||||
label3.Name = "label3";
|
||||
//
|
||||
// comboBox_Version
|
||||
//
|
||||
resources.ApplyResources(comboBox_Version, "comboBox_Version");
|
||||
comboBox_Version.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_Version.FormattingEnabled = true;
|
||||
comboBox_Version.Name = "comboBox_Version";
|
||||
comboBox_Version.Sorted = true;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel2, "tableLayoutPanel2");
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
resources.ApplyResources(button_Ok, "button_Ok");
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
resources.ApplyResources(button_Cancel, "button_Cancel");
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// skelFileListBox
|
||||
//
|
||||
resources.ApplyResources(skelFileListBox, "skelFileListBox");
|
||||
tableLayoutPanel1.SetColumnSpan(skelFileListBox, 2);
|
||||
skelFileListBox.Name = "skelFileListBox";
|
||||
//
|
||||
// BatchOpenSpineDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
Controls.Add(panel);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "BatchOpenSpineDialog";
|
||||
ShowInTaskbar = false;
|
||||
panel.ResumeLayout(false);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
private Panel panel;
|
||||
#endregion
|
||||
private Panel panel;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SpineViewer.Spine;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -21,21 +22,21 @@ namespace SpineViewer.Dialogs
|
||||
public BatchOpenSpineDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
comboBox_Version.DataSource = VersionHelper.Names.ToList();
|
||||
comboBox_Version.DataSource = SpineUtils.Names.ToList();
|
||||
comboBox_Version.DisplayMember = "Value";
|
||||
comboBox_Version.ValueMember = "Key";
|
||||
comboBox_Version.SelectedValue = Spine.Version.Auto;
|
||||
comboBox_Version.SelectedValue = SpineVersion.Auto;
|
||||
}
|
||||
|
||||
private void button_Ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
var version = (Spine.Version)comboBox_Version.SelectedValue;
|
||||
var version = (SpineVersion)comboBox_Version.SelectedValue;
|
||||
|
||||
var items = skelFileListBox.Items;
|
||||
|
||||
if (items.Count <= 0)
|
||||
{
|
||||
MessageBox.Info("未选择任何文件");
|
||||
MessagePopup.Info("未选择任何文件", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,14 +44,14 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
if (!File.Exists(p))
|
||||
{
|
||||
MessageBox.Info($"{p}", "skel文件不存在");
|
||||
MessagePopup.Info($"{p}", Properties.Resources.skelNotExist);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (version != Spine.Version.Auto && !Spine.Spine.ImplementedVersions.Contains(version))
|
||||
if (version != SpineVersion.Auto && !Spine.SpineObject.HasImplementation(version))
|
||||
{
|
||||
MessageBox.Info($"{version.GetName()} 版本尚未实现(咕咕咕~)");
|
||||
MessagePopup.Info($"{version.GetName()} 版本尚未实现(咕咕咕~)", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,12 +68,12 @@ namespace SpineViewer.Dialogs
|
||||
/// <summary>
|
||||
/// 批量打开对话框结果
|
||||
/// </summary>
|
||||
public class BatchOpenSpineDialogResult(Spine.Version version, string[] skelPaths)
|
||||
public class BatchOpenSpineDialogResult(SpineVersion version, string[] skelPaths)
|
||||
{
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
public Spine.Version Version => version;
|
||||
public SpineVersion Version => version;
|
||||
|
||||
/// <summary>
|
||||
/// 路径列表
|
||||
|
||||
3297
SpineViewer/Dialogs/BatchOpenSpineDialog.en.resx
Normal file
3297
SpineViewer/Dialogs/BatchOpenSpineDialog.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -118,6 +118,102 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="skelFileListBox.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>684, 234</value>
|
||||
</data>
|
||||
<data name=">>panel.Name" xml:space="preserve">
|
||||
<value>panel</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>133, 28</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>682, 32</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Ok.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Right</value>
|
||||
</data>
|
||||
<data name="label4.Text" xml:space="preserve">
|
||||
<value>说明:批量导入只需要选择skel文件,atlas文件需要在同目录下并且与skel文件名相同</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>1, 46</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>label4.Name" xml:space="preserve">
|
||||
<value>label4</value>
|
||||
</data>
|
||||
<data name=">>panel.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 339</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="label3.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="panel.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>36, 12, 36, 8</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>22, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Ok.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name=">>label3.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>label4.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>panel.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="button_Ok.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 22, 2</value>
|
||||
</data>
|
||||
<data name="panel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="panel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3264,4 +3360,226 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="label4.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>11, 12</value>
|
||||
</data>
|
||||
<data name=">>label3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>1, 2, 1, 2</value>
|
||||
</data>
|
||||
<data name="label4.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleCenter</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Name" xml:space="preserve">
|
||||
<value>button_Ok</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>批量打开骨骼</value>
|
||||
</data>
|
||||
<data name=">>label4.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="button_Ok.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>238, 2</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>label3.Name" xml:space="preserve">
|
||||
<value>label3</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>686, 373</value>
|
||||
</data>
|
||||
<data name=">>label4.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Ok.Text" xml:space="preserve">
|
||||
<value>确认</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Name" xml:space="preserve">
|
||||
<value>button_Cancel</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>363, 2</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>BatchOpenSpineDialog</value>
|
||||
</data>
|
||||
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 288</value>
|
||||
</data>
|
||||
<data name="panel.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="label4.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label3.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="label4.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 12, 11, 12</value>
|
||||
</data>
|
||||
<data name="label4.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Name" xml:space="preserve">
|
||||
<value>skelFileListBox</value>
|
||||
</data>
|
||||
<data name="panel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>664, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 25, 2, 2</value>
|
||||
</data>
|
||||
<data name="label3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>758, 393</value>
|
||||
</data>
|
||||
<data name="label4.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>42, 20</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>48, 284</value>
|
||||
</data>
|
||||
<data name="button_Cancel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Name" xml:space="preserve">
|
||||
<value>comboBox_Version</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="panel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>758, 393</value>
|
||||
</data>
|
||||
<data name="button_Ok.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>15</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label4" Row="0" RowSpan="1" Column="0" ColumnSpan="4" /><Control Name="label3" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboBox_Version" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="tableLayoutPanel2" Row="3" RowSpan="1" Column="0" ColumnSpan="4" /><Control Name="skelFileListBox" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,Percent,100,AutoSize,0,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.RowCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>版本:</value>
|
||||
</data>
|
||||
<data name=">>panel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Type" xml:space="preserve">
|
||||
<value>SpineViewer.Controls.SkelFileListBox, SpineViewer, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>label3.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>36, 12</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
180
SpineViewer/Dialogs/ConvertFileFormatDialog.Designer.cs
generated
180
SpineViewer/Dialogs/ConvertFileFormatDialog.Designer.cs
generated
@@ -31,6 +31,7 @@
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConvertFileFormatDialog));
|
||||
panel = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label5 = new Label();
|
||||
comboBox_TargetVersion = new ComboBox();
|
||||
flowLayoutPanel_TargetFormat = new FlowLayoutPanel();
|
||||
radioButton_BinaryTarget = new RadioButton();
|
||||
@@ -44,230 +45,173 @@
|
||||
button_Cancel = new Button();
|
||||
label2 = new Label();
|
||||
skelFileListBox = new SpineViewer.Controls.SkelFileListBox();
|
||||
openFileDialog_Skel = new OpenFileDialog();
|
||||
tableLayoutPanel3 = new TableLayoutPanel();
|
||||
textBox_OutputDir = new TextBox();
|
||||
button_SelectOutputDir = new Button();
|
||||
folderBrowserDialog_Output = new FolderBrowserDialog();
|
||||
panel.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
flowLayoutPanel_TargetFormat.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
tableLayoutPanel3.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel
|
||||
//
|
||||
resources.ApplyResources(panel, "panel");
|
||||
panel.Controls.Add(tableLayoutPanel1);
|
||||
panel.Dock = DockStyle.Fill;
|
||||
panel.Location = new Point(0, 0);
|
||||
panel.Name = "panel";
|
||||
panel.Padding = new Padding(50, 15, 50, 10);
|
||||
panel.Size = new Size(1051, 538);
|
||||
panel.TabIndex = 2;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.ColumnCount = 2;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.Controls.Add(comboBox_TargetVersion, 1, 3);
|
||||
tableLayoutPanel1.Controls.Add(flowLayoutPanel_TargetFormat, 1, 4);
|
||||
tableLayoutPanel1.Controls.Add(label1, 0, 3);
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(label5, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_TargetVersion, 1, 4);
|
||||
tableLayoutPanel1.Controls.Add(flowLayoutPanel_TargetFormat, 1, 5);
|
||||
tableLayoutPanel1.Controls.Add(label1, 0, 4);
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_SourceVersion, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 5);
|
||||
tableLayoutPanel1.Controls.Add(label2, 0, 4);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 3);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_SourceVersion, 1, 3);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 6);
|
||||
tableLayoutPanel1.Controls.Add(label2, 0, 5);
|
||||
tableLayoutPanel1.Controls.Add(skelFileListBox, 0, 1);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(50, 15);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel3, 1, 2);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 6;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(951, 513);
|
||||
tableLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
resources.ApplyResources(label5, "label5");
|
||||
label5.Name = "label5";
|
||||
//
|
||||
// comboBox_TargetVersion
|
||||
//
|
||||
comboBox_TargetVersion.Anchor = AnchorStyles.Left;
|
||||
resources.ApplyResources(comboBox_TargetVersion, "comboBox_TargetVersion");
|
||||
comboBox_TargetVersion.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_TargetVersion.FormattingEnabled = true;
|
||||
comboBox_TargetVersion.Location = new Point(95, 365);
|
||||
comboBox_TargetVersion.Name = "comboBox_TargetVersion";
|
||||
comboBox_TargetVersion.Size = new Size(182, 32);
|
||||
comboBox_TargetVersion.Sorted = true;
|
||||
comboBox_TargetVersion.TabIndex = 21;
|
||||
//
|
||||
// flowLayoutPanel_TargetFormat
|
||||
//
|
||||
flowLayoutPanel_TargetFormat.AutoSize = true;
|
||||
resources.ApplyResources(flowLayoutPanel_TargetFormat, "flowLayoutPanel_TargetFormat");
|
||||
flowLayoutPanel_TargetFormat.Controls.Add(radioButton_BinaryTarget);
|
||||
flowLayoutPanel_TargetFormat.Controls.Add(radioButton_JsonTarget);
|
||||
flowLayoutPanel_TargetFormat.Dock = DockStyle.Fill;
|
||||
flowLayoutPanel_TargetFormat.Location = new Point(95, 403);
|
||||
flowLayoutPanel_TargetFormat.Name = "flowLayoutPanel_TargetFormat";
|
||||
flowLayoutPanel_TargetFormat.Size = new Size(853, 34);
|
||||
flowLayoutPanel_TargetFormat.TabIndex = 19;
|
||||
//
|
||||
// radioButton_BinaryTarget
|
||||
//
|
||||
radioButton_BinaryTarget.AutoSize = true;
|
||||
radioButton_BinaryTarget.Location = new Point(3, 3);
|
||||
resources.ApplyResources(radioButton_BinaryTarget, "radioButton_BinaryTarget");
|
||||
radioButton_BinaryTarget.Name = "radioButton_BinaryTarget";
|
||||
radioButton_BinaryTarget.Size = new Size(151, 28);
|
||||
radioButton_BinaryTarget.TabIndex = 17;
|
||||
radioButton_BinaryTarget.Text = "二进制 (*.skel)";
|
||||
radioButton_BinaryTarget.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// radioButton_JsonTarget
|
||||
//
|
||||
radioButton_JsonTarget.AutoSize = true;
|
||||
resources.ApplyResources(radioButton_JsonTarget, "radioButton_JsonTarget");
|
||||
radioButton_JsonTarget.Checked = true;
|
||||
radioButton_JsonTarget.Location = new Point(160, 3);
|
||||
radioButton_JsonTarget.Name = "radioButton_JsonTarget";
|
||||
radioButton_JsonTarget.Size = new Size(135, 28);
|
||||
radioButton_JsonTarget.TabIndex = 18;
|
||||
radioButton_JsonTarget.TabStop = true;
|
||||
radioButton_JsonTarget.Text = "文本 (*.json)";
|
||||
radioButton_JsonTarget.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Anchor = AnchorStyles.Right;
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new Point(3, 369);
|
||||
resources.ApplyResources(label1, "label1");
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(86, 24);
|
||||
label1.TabIndex = 15;
|
||||
label1.Text = "目标版本:";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.AutoSize = true;
|
||||
resources.ApplyResources(label4, "label4");
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Dock = DockStyle.Fill;
|
||||
label4.Location = new Point(15, 15);
|
||||
label4.Margin = new Padding(15);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new Size(921, 24);
|
||||
label4.TabIndex = 14;
|
||||
label4.Text = "说明:将在每个文件同级目录下生成目标格式后缀的文件,会覆盖已存在文件";
|
||||
label4.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Anchor = AnchorStyles.Right;
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new Point(21, 331);
|
||||
resources.ApplyResources(label3, "label3");
|
||||
label3.Name = "label3";
|
||||
label3.Size = new Size(68, 24);
|
||||
label3.TabIndex = 12;
|
||||
label3.Text = "源版本:";
|
||||
//
|
||||
// comboBox_SourceVersion
|
||||
//
|
||||
comboBox_SourceVersion.Anchor = AnchorStyles.Left;
|
||||
resources.ApplyResources(comboBox_SourceVersion, "comboBox_SourceVersion");
|
||||
comboBox_SourceVersion.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_SourceVersion.FormattingEnabled = true;
|
||||
comboBox_SourceVersion.Location = new Point(95, 327);
|
||||
comboBox_SourceVersion.Name = "comboBox_SourceVersion";
|
||||
comboBox_SourceVersion.Size = new Size(182, 32);
|
||||
comboBox_SourceVersion.Sorted = true;
|
||||
comboBox_SourceVersion.TabIndex = 13;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
tableLayoutPanel2.AutoSize = true;
|
||||
tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
tableLayoutPanel2.ColumnCount = 2;
|
||||
resources.ApplyResources(tableLayoutPanel2, "tableLayoutPanel2");
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel2.Location = new Point(3, 470);
|
||||
tableLayoutPanel2.Margin = new Padding(3, 30, 3, 3);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
tableLayoutPanel2.RowCount = 1;
|
||||
tableLayoutPanel2.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel2.Size = new Size(945, 40);
|
||||
tableLayoutPanel2.TabIndex = 11;
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
button_Ok.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
button_Ok.Location = new Point(330, 3);
|
||||
button_Ok.Margin = new Padding(3, 3, 30, 3);
|
||||
resources.ApplyResources(button_Ok, "button_Ok");
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.Size = new Size(112, 34);
|
||||
button_Ok.TabIndex = 7;
|
||||
button_Ok.Text = "确认";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
button_Cancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
|
||||
button_Cancel.Location = new Point(502, 3);
|
||||
button_Cancel.Margin = new Padding(30, 3, 3, 3);
|
||||
resources.ApplyResources(button_Cancel, "button_Cancel");
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.Size = new Size(112, 34);
|
||||
button_Cancel.TabIndex = 8;
|
||||
button_Cancel.Text = "取消";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.Anchor = AnchorStyles.Right;
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new Point(3, 408);
|
||||
resources.ApplyResources(label2, "label2");
|
||||
label2.Name = "label2";
|
||||
label2.Size = new Size(86, 24);
|
||||
label2.TabIndex = 16;
|
||||
label2.Text = "目标格式:";
|
||||
//
|
||||
// skelFileListBox
|
||||
//
|
||||
resources.ApplyResources(skelFileListBox, "skelFileListBox");
|
||||
tableLayoutPanel1.SetColumnSpan(skelFileListBox, 2);
|
||||
skelFileListBox.Dock = DockStyle.Fill;
|
||||
skelFileListBox.Location = new Point(3, 57);
|
||||
skelFileListBox.Name = "skelFileListBox";
|
||||
skelFileListBox.Size = new Size(945, 264);
|
||||
skelFileListBox.TabIndex = 20;
|
||||
//
|
||||
// openFileDialog_Skel
|
||||
// tableLayoutPanel3
|
||||
//
|
||||
openFileDialog_Skel.AddExtension = false;
|
||||
openFileDialog_Skel.AddToRecent = false;
|
||||
openFileDialog_Skel.Filter = "skel 文件 (*.skel; *.json)|*.skel;*.json|二进制文件 (*.skel)|*.skel|文本文件 (*.json)|*.json|所有文件 (*.*)|*.*";
|
||||
openFileDialog_Skel.Multiselect = true;
|
||||
openFileDialog_Skel.Title = "批量选择skel文件";
|
||||
resources.ApplyResources(tableLayoutPanel3, "tableLayoutPanel3");
|
||||
tableLayoutPanel3.Controls.Add(textBox_OutputDir, 1, 0);
|
||||
tableLayoutPanel3.Controls.Add(button_SelectOutputDir, 2, 0);
|
||||
tableLayoutPanel3.Name = "tableLayoutPanel3";
|
||||
//
|
||||
// textBox_OutputDir
|
||||
//
|
||||
resources.ApplyResources(textBox_OutputDir, "textBox_OutputDir");
|
||||
textBox_OutputDir.Name = "textBox_OutputDir";
|
||||
//
|
||||
// button_SelectOutputDir
|
||||
//
|
||||
resources.ApplyResources(button_SelectOutputDir, "button_SelectOutputDir");
|
||||
button_SelectOutputDir.Name = "button_SelectOutputDir";
|
||||
button_SelectOutputDir.UseVisualStyleBackColor = true;
|
||||
button_SelectOutputDir.Click += button_SelectOutputDir_Click;
|
||||
//
|
||||
// folderBrowserDialog_Output
|
||||
//
|
||||
resources.ApplyResources(folderBrowserDialog_Output, "folderBrowserDialog_Output");
|
||||
//
|
||||
// ConvertFileFormatDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
ClientSize = new Size(1051, 538);
|
||||
Controls.Add(panel);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ConvertFileFormatDialog";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "骨骼文件格式转换";
|
||||
panel.ResumeLayout(false);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
flowLayoutPanel_TargetFormat.ResumeLayout(false);
|
||||
flowLayoutPanel_TargetFormat.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
tableLayoutPanel3.ResumeLayout(false);
|
||||
tableLayoutPanel3.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
@@ -281,7 +225,6 @@
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
private Button button_Cancel;
|
||||
private OpenFileDialog openFileDialog_Skel;
|
||||
private Label label1;
|
||||
private Label label2;
|
||||
private FlowLayoutPanel flowLayoutPanel_TargetFormat;
|
||||
@@ -289,5 +232,10 @@
|
||||
private RadioButton radioButton_JsonTarget;
|
||||
private Controls.SkelFileListBox skelFileListBox;
|
||||
private ComboBox comboBox_TargetVersion;
|
||||
private FolderBrowserDialog folderBrowserDialog_Output;
|
||||
private TableLayoutPanel tableLayoutPanel3;
|
||||
private TextBox textBox_OutputDir;
|
||||
private Button button_SelectOutputDir;
|
||||
private Label label5;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using SpineViewer.Spine;
|
||||
using NLog;
|
||||
using SpineViewer.Spine;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -13,6 +15,8 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ConvertFileFormatDialog : Form
|
||||
{
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 对话框结果, 取消时为 null
|
||||
/// </summary>
|
||||
@@ -22,56 +26,95 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
comboBox_SourceVersion.DataSource = VersionHelper.Names.ToList();
|
||||
comboBox_SourceVersion.DataSource = SpineUtils.Names.ToList();
|
||||
comboBox_SourceVersion.DisplayMember = "Value";
|
||||
comboBox_SourceVersion.ValueMember = "Key";
|
||||
comboBox_SourceVersion.SelectedValue = Spine.Version.Auto;
|
||||
comboBox_SourceVersion.SelectedValue = SpineVersion.Auto;
|
||||
|
||||
// 目标版本不包含自动
|
||||
var versionsWithoutAuto = VersionHelper.Names.ToDictionary();
|
||||
versionsWithoutAuto.Remove(Spine.Version.Auto);
|
||||
var versionsWithoutAuto = SpineUtils.Names.ToDictionary();
|
||||
versionsWithoutAuto.Remove(SpineVersion.Auto);
|
||||
comboBox_TargetVersion.DataSource = versionsWithoutAuto.ToList();
|
||||
comboBox_TargetVersion.DisplayMember = "Value";
|
||||
comboBox_TargetVersion.ValueMember = "Key";
|
||||
comboBox_TargetVersion.SelectedValue = Spine.Version.V38;
|
||||
comboBox_TargetVersion.SelectedValue = SpineVersion.V38;
|
||||
}
|
||||
|
||||
private void button_SelectOutputDir_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (folderBrowserDialog_Output.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
textBox_OutputDir.Text = Path.GetFullPath(folderBrowserDialog_Output.SelectedPath);
|
||||
}
|
||||
|
||||
private void button_Ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
var sourceVersion = (Spine.Version)comboBox_SourceVersion.SelectedValue;
|
||||
var targetVersion = (Spine.Version)comboBox_TargetVersion.SelectedValue;
|
||||
var outputDir = textBox_OutputDir.Text;
|
||||
var sourceVersion = (SpineVersion)comboBox_SourceVersion.SelectedValue;
|
||||
var targetVersion = (SpineVersion)comboBox_TargetVersion.SelectedValue;
|
||||
var jsonTarget = radioButton_JsonTarget.Checked;
|
||||
|
||||
var items = skelFileListBox.Items;
|
||||
|
||||
if (items.Count <= 0)
|
||||
{
|
||||
MessageBox.Info("未选择任何文件");
|
||||
MessagePopup.Info("未选择任何文件", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(outputDir))
|
||||
{
|
||||
outputDir = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
outputDir = Path.GetFullPath(outputDir);
|
||||
if (!Directory.Exists(outputDir))
|
||||
{
|
||||
if (MessagePopup.Quest("输出文件夹不存在,是否创建?", Properties.Resources.msgBoxQuest) == DialogResult.OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(outputDir);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex.ToString());
|
||||
logger.Error("Failed to create output dir {}", outputDir);
|
||||
MessagePopup.Error(ex.ToString(), Properties.Resources.msgBoxError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string p in items)
|
||||
{
|
||||
if (!File.Exists(p))
|
||||
{
|
||||
MessageBox.Info($"{p}", "skel文件不存在");
|
||||
MessagePopup.Info($"{p}", Properties.Resources.skelNotExist);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceVersion != Spine.Version.Auto && !SkeletonConverter.ImplementedVersions.Contains(sourceVersion))
|
||||
if (sourceVersion != SpineVersion.Auto && !SkeletonConverter.HasImplementation(sourceVersion))
|
||||
{
|
||||
MessageBox.Info($"{sourceVersion.GetName()} 版本尚未实现(咕咕咕~)");
|
||||
MessagePopup.Info($"{sourceVersion.GetName()} 版本尚未实现(咕咕咕~)", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SkeletonConverter.ImplementedVersions.Contains(targetVersion))
|
||||
if (!SkeletonConverter.HasImplementation(targetVersion))
|
||||
{
|
||||
MessageBox.Info($"{targetVersion.GetName()} 版本尚未实现(咕咕咕~)");
|
||||
MessagePopup.Info($"{targetVersion.GetName()} 版本尚未实现(咕咕咕~)", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
Result = new(items.Cast<string>().ToArray(), sourceVersion, targetVersion, jsonTarget);
|
||||
Result = new(outputDir, items.Cast<string>().ToArray(), sourceVersion, targetVersion, jsonTarget);
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
@@ -84,8 +127,13 @@ namespace SpineViewer.Dialogs
|
||||
/// <summary>
|
||||
/// 文件格式转换对话框结果包装类
|
||||
/// </summary>
|
||||
public class ConvertFileFormatDialogResult(string[] skelPaths, Spine.Version sourceVersion, Spine.Version targetVersion, bool jsonTarget)
|
||||
public class ConvertFileFormatDialogResult(string? outputDir, string[] skelPaths, SpineVersion sourceVersion, SpineVersion targetVersion, bool jsonTarget)
|
||||
{
|
||||
/// <summary>
|
||||
/// 输出文件夹, 如果为空, 则将转换后的文件转换到各自的文件夹下
|
||||
/// </summary>
|
||||
public string? OutputDir => outputDir;
|
||||
|
||||
/// <summary>
|
||||
/// 骨骼文件路径列表
|
||||
/// </summary>
|
||||
@@ -94,12 +142,12 @@ namespace SpineViewer.Dialogs
|
||||
/// <summary>
|
||||
/// 源版本
|
||||
/// </summary>
|
||||
public Spine.Version SourceVersion => sourceVersion;
|
||||
public SpineVersion SourceVersion => sourceVersion;
|
||||
|
||||
/// <summary>
|
||||
/// 目标版本
|
||||
/// </summary>
|
||||
public Spine.Version TargetVersion => targetVersion;
|
||||
public SpineVersion TargetVersion => targetVersion;
|
||||
|
||||
/// <summary>
|
||||
/// 目标格式是否为 Json
|
||||
|
||||
3351
SpineViewer/Dialogs/ConvertFileFormatDialog.en.resx
Normal file
3351
SpineViewer/Dialogs/ConvertFileFormatDialog.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -117,10 +117,553 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="openFileDialog_Skel.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>92, 26</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="skelFileListBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>1, 2, 1, 2</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.ZOrder" xml:space="preserve">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_SelectOutputDir.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="button_Cancel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel_TargetFormat.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="button_Ok.Text" xml:space="preserve">
|
||||
<value>确认</value>
|
||||
</data>
|
||||
<data name=">>label1.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>textBox_OutputDir.Name" xml:space="preserve">
|
||||
<value>textBox_OutputDir</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="panel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name=">>radioButton_JsonTarget.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.RadioButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>folderBrowserDialog_Output.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.FolderBrowserDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Ok.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>111, 34</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name=">>button_SelectOutputDir.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="comboBox_SourceVersion.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name=">>textBox_OutputDir.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>1050, 702</value>
|
||||
</data>
|
||||
<data name=">>panel.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="textBox_OutputDir.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>comboBox_TargetVersion.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="radioButton_JsonTarget.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>135, 28</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Cancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left</value>
|
||||
</data>
|
||||
<data name="label5.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 473</value>
|
||||
</data>
|
||||
<data name="label4.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>15, 14</value>
|
||||
</data>
|
||||
<data name=">>radioButton_JsonTarget.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_SelectOutputDir.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left, Right</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>950, 678</value>
|
||||
</data>
|
||||
<data name=">>label1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="comboBox_TargetVersion.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>113, 542</value>
|
||||
</data>
|
||||
<data name="label2.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>16</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="panel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="label3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel</value>
|
||||
</data>
|
||||
<data name=">>radioButton_BinaryTarget.Name" xml:space="preserve">
|
||||
<value>radioButton_BinaryTarget</value>
|
||||
</data>
|
||||
<data name="label5.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="textBox_OutputDir.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 4</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>comboBox_SourceVersion.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="comboBox_SourceVersion.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="comboBox_SourceVersion.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.ZOrder" xml:space="preserve">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name=">>folderBrowserDialog_Output.Name" xml:space="preserve">
|
||||
<value>folderBrowserDialog_Output</value>
|
||||
</data>
|
||||
<data name="label5.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>23</value>
|
||||
</data>
|
||||
<data name=">>label2.Name" xml:space="preserve">
|
||||
<value>label2</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_Ok.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>331, 2</value>
|
||||
</data>
|
||||
<data name="radioButton_BinaryTarget.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="button_Ok.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 30, 2</value>
|
||||
</data>
|
||||
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>39, 510</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="textBox_OutputDir.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>796, 30</value>
|
||||
</data>
|
||||
<data name=">>radioButton_BinaryTarget.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Name" xml:space="preserve">
|
||||
<value>button_Cancel</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>110, 466</value>
|
||||
</data>
|
||||
<data name="label4.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>panel.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="radioButton_JsonTarget.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name=">>label1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="label4.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleCenter</value>
|
||||
</data>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>源版本:</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_SelectOutputDir.Text" xml:space="preserve">
|
||||
<value>...</value>
|
||||
</data>
|
||||
<data name="panel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="label4.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name=">>radioButton_JsonTarget.Name" xml:space="preserve">
|
||||
<value>radioButton_JsonTarget</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>1, 54</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>label4.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="comboBox_TargetVersion.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="radioButton_JsonTarget.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>18</value>
|
||||
</data>
|
||||
<data name="label4.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_SelectOutputDir.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="comboBox_SourceVersion.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>181, 32</value>
|
||||
</data>
|
||||
<data name=">>button_SelectOutputDir.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="radioButton_BinaryTarget.Text" xml:space="preserve">
|
||||
<value>二进制 (*.skel)</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>920, 24</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>comboBox_SourceVersion.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel_TargetFormat.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>19</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel_TargetFormat.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label5.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.RowCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label5.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left, Right</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>840, 38</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Name" xml:space="preserve">
|
||||
<value>button_Ok</value>
|
||||
</data>
|
||||
<data name=">>textBox_OutputDir.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel3</value>
|
||||
</data>
|
||||
<data name="label1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>15</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>20</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel_TargetFormat.Name" xml:space="preserve">
|
||||
<value>flowLayoutPanel_TargetFormat</value>
|
||||
</data>
|
||||
<data name=">>label3.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>502, 2</value>
|
||||
</data>
|
||||
<data name=">>comboBox_SourceVersion.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="radioButton_BinaryTarget.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 2</value>
|
||||
</data>
|
||||
<data name="button_SelectOutputDir.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>32, 34</value>
|
||||
</data>
|
||||
<data name="comboBox_SourceVersion.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>113, 506</value>
|
||||
</data>
|
||||
<data name="textBox_OutputDir.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left, Right</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>ConvertFileFormatDialog</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>label5.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel_TargetFormat.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>label2.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>label3.Name" xml:space="preserve">
|
||||
<value>label3</value>
|
||||
</data>
|
||||
<data name="label4.Text" xml:space="preserve">
|
||||
<value>说明:输出文件夹留空则在每个文件同级目录下生成目标格式后缀的文件,视情况会覆盖已存在文件</value>
|
||||
</data>
|
||||
<data name=">>comboBox_SourceVersion.Name" xml:space="preserve">
|
||||
<value>comboBox_SourceVersion</value>
|
||||
</data>
|
||||
<data name=">>radioButton_BinaryTarget.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.RadioButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Ok.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>骨骼文件格式转换</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel_TargetFormat.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>110, 576</value>
|
||||
</data>
|
||||
<data name="comboBox_TargetVersion.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>181, 32</value>
|
||||
</data>
|
||||
<data name=">>label5.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="label2.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="radioButton_JsonTarget.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>160, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label5" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboBox_TargetVersion" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="flowLayoutPanel_TargetFormat" Row="5" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label1" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label4" Row="0" RowSpan="1" Column="0" ColumnSpan="4" /><Control Name="label3" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboBox_SourceVersion" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="tableLayoutPanel2" Row="6" RowSpan="1" Column="0" ColumnSpan="4" /><Control Name="label2" Row="5" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="skelFileListBox" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /><Control Name="tableLayoutPanel3" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,Percent,100,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,Absolute,24" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.RowCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label2.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="panel.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>50, 14, 50, 10</value>
|
||||
</data>
|
||||
<data name="radioButton_BinaryTarget.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>151, 28</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel_TargetFormat.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>840, 32</value>
|
||||
</data>
|
||||
<data name="label2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>21, 580</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel3.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel3</value>
|
||||
</data>
|
||||
<data name="label2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>86, 24</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel_TargetFormat.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel3.ZOrder" xml:space="preserve">
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel_TargetFormat.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="label1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel3.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Name" xml:space="preserve">
|
||||
<value>skelFileListBox</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>111, 34</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel_TargetFormat.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>label2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 638</value>
|
||||
</data>
|
||||
<data name="radioButton_BinaryTarget.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>17</value>
|
||||
</data>
|
||||
<data name=">>label5.Name" xml:space="preserve">
|
||||
<value>label5</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="textBox_OutputDir" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="button_SelectOutputDir" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100,AutoSize,0" /><Rows Styles="Percent,100" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>radioButton_JsonTarget.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel_TargetFormat</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>11, 24</value>
|
||||
</data>
|
||||
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>21, 546</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="textBox_OutputDir.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name=">>label4.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>948, 410</value>
|
||||
</data>
|
||||
<data name="label3.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label5.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>104, 24</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>1050, 702</value>
|
||||
</data>
|
||||
<data name=">>label3.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>86, 24</value>
|
||||
</data>
|
||||
<data name=">>label4.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_SelectOutputDir.Name" xml:space="preserve">
|
||||
<value>button_SelectOutputDir</value>
|
||||
</data>
|
||||
<data name="panel.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>label4.Name" xml:space="preserve">
|
||||
<value>label4</value>
|
||||
</data>
|
||||
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<data name=">>comboBox_TargetVersion.Name" xml:space="preserve">
|
||||
<value>comboBox_TargetVersion</value>
|
||||
</data>
|
||||
<data name=">>button_SelectOutputDir.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel3</value>
|
||||
</data>
|
||||
<data name="radioButton_JsonTarget.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 30, 3, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>944, 38</value>
|
||||
</data>
|
||||
<data name="button_SelectOutputDir.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>805, 2</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3267,4 +3810,94 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>68, 24</value>
|
||||
</data>
|
||||
<data name="label5.Text" xml:space="preserve">
|
||||
<value>输出文件夹:</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>50, 14</value>
|
||||
</data>
|
||||
<data name="comboBox_TargetVersion.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>21</value>
|
||||
</data>
|
||||
<data name="button_SelectOutputDir.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name=">>comboBox_TargetVersion.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_Ok.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Right</value>
|
||||
</data>
|
||||
<data name=">>panel.Name" xml:space="preserve">
|
||||
<value>panel</value>
|
||||
</data>
|
||||
<data name=">>label1.Name" xml:space="preserve">
|
||||
<value>label1</value>
|
||||
</data>
|
||||
<data name="label4.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 14, 15, 14</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>30, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="radioButton_JsonTarget.Text" xml:space="preserve">
|
||||
<value>文本 (*.json)</value>
|
||||
</data>
|
||||
<data name="label2.Text" xml:space="preserve">
|
||||
<value>目标格式:</value>
|
||||
</data>
|
||||
<data name=">>radioButton_BinaryTarget.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel_TargetFormat</value>
|
||||
</data>
|
||||
<data name=">>label2.ZOrder" xml:space="preserve">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="comboBox_TargetVersion.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name=">>panel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>comboBox_TargetVersion.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>目标版本:</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Type" xml:space="preserve">
|
||||
<value>SpineViewer.Controls.SkelFileListBox, SpineViewer, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name="radioButton_BinaryTarget.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>textBox_OutputDir.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel3.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>22</value>
|
||||
</data>
|
||||
<data name="button_SelectOutputDir.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<metadata name="folderBrowserDialog_Output.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>36, 22</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
146
SpineViewer/Dialogs/DiagnosticsDialog.Designer.cs
generated
146
SpineViewer/Dialogs/DiagnosticsDialog.Designer.cs
generated
@@ -20,96 +20,68 @@
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DiagnosticsDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
button_Copy = new Button();
|
||||
propertyGrid = new PropertyGrid();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(0, 0);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(50, 15, 50, 10);
|
||||
panel1.Size = new Size(901, 452);
|
||||
panel1.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.AutoSize = true;
|
||||
tableLayoutPanel1.ColumnCount = 1;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.Controls.Add(button_Copy, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(propertyGrid, 0, 0);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(50, 15);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 2;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(801, 427);
|
||||
tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// button_Copy
|
||||
//
|
||||
button_Copy.Anchor = AnchorStyles.None;
|
||||
button_Copy.AutoSize = true;
|
||||
button_Copy.Location = new Point(326, 390);
|
||||
button_Copy.Margin = new Padding(3, 10, 3, 3);
|
||||
button_Copy.Name = "button_Copy";
|
||||
button_Copy.Padding = new Padding(10, 0, 10, 0);
|
||||
button_Copy.Size = new Size(148, 34);
|
||||
button_Copy.TabIndex = 12;
|
||||
button_Copy.Text = "复制到剪贴板";
|
||||
button_Copy.UseVisualStyleBackColor = true;
|
||||
button_Copy.Click += button_Copy_Click;
|
||||
//
|
||||
// propertyGrid
|
||||
//
|
||||
propertyGrid.Dock = DockStyle.Fill;
|
||||
propertyGrid.HelpVisible = false;
|
||||
propertyGrid.Location = new Point(3, 3);
|
||||
propertyGrid.Name = "propertyGrid";
|
||||
propertyGrid.Size = new Size(795, 374);
|
||||
propertyGrid.TabIndex = 13;
|
||||
propertyGrid.ToolbarVisible = false;
|
||||
//
|
||||
// DiagnosticsDialog
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(901, 452);
|
||||
Controls.Add(panel1);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "DiagnosticsDialog";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "诊断信息";
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DiagnosticsDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
button_Copy = new Button();
|
||||
propertyGrid = new PropertyGrid();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(button_Copy, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(propertyGrid, 0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// button_Copy
|
||||
//
|
||||
resources.ApplyResources(button_Copy, "button_Copy");
|
||||
button_Copy.Name = "button_Copy";
|
||||
button_Copy.UseVisualStyleBackColor = true;
|
||||
button_Copy.Click += button_Copy_Click;
|
||||
//
|
||||
// propertyGrid
|
||||
//
|
||||
resources.ApplyResources(propertyGrid, "propertyGrid");
|
||||
propertyGrid.Name = "propertyGrid";
|
||||
propertyGrid.ToolbarVisible = false;
|
||||
//
|
||||
// DiagnosticsDialog
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(panel1);
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "DiagnosticsDialog";
|
||||
ShowInTaskbar = false;
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Button button_Copy;
|
||||
private PropertyGrid propertyGrid;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Win32;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -26,7 +27,29 @@ namespace SpineViewer.Dialogs
|
||||
|
||||
private class DiagnosticsInformation
|
||||
{
|
||||
[Category("Versions")]
|
||||
[Category("Hardware")]
|
||||
public string CPU
|
||||
{
|
||||
get => Registry.GetValue(@"HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0", "ProcessorNameString", "Unknown").ToString();
|
||||
}
|
||||
|
||||
[Category("Hardware")]
|
||||
public string Memory
|
||||
{
|
||||
get => $"{new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory / 1024f / 1024f / 1024f:F1} GB";
|
||||
}
|
||||
|
||||
[Category("Hardware")]
|
||||
public string GPU
|
||||
{
|
||||
get
|
||||
{
|
||||
var searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_VideoController");
|
||||
return string.Join("; ", searcher.Get().Cast<ManagementObject>().Select(mo => mo["Name"].ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Software")]
|
||||
public string WindowsVersion
|
||||
{
|
||||
get
|
||||
@@ -39,44 +62,28 @@ namespace SpineViewer.Dialogs
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Versions")]
|
||||
[Category("Software")]
|
||||
public string Version
|
||||
{
|
||||
get => Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
}
|
||||
|
||||
[Category("Versions")]
|
||||
[Category("Software")]
|
||||
public string DotNetVersion
|
||||
{
|
||||
get => Environment.Version.ToString();
|
||||
}
|
||||
|
||||
[Category("Versions")]
|
||||
[Category("Software")]
|
||||
public string SFMLVersion
|
||||
{
|
||||
get => typeof(SFML.ObjectBase).Assembly.GetName().Version.ToString();
|
||||
}
|
||||
|
||||
[Category("Hardwares")]
|
||||
public string CPU
|
||||
[Category("Software")]
|
||||
public string FFMpegCoreVersion
|
||||
{
|
||||
get => Registry.GetValue(@"HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0", "ProcessorNameString", "Unknown").ToString();
|
||||
}
|
||||
|
||||
[Category("Hardwares")]
|
||||
public string Memory
|
||||
{
|
||||
get => $"{new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory / 1024f / 1024f / 1024f:F1} GB";
|
||||
}
|
||||
|
||||
[Category("Hardwares")]
|
||||
public string GPU
|
||||
{
|
||||
get
|
||||
{
|
||||
var searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_VideoController");
|
||||
return string.Join("; ", searcher.Get().Cast<ManagementObject>().Select(mo => mo["Name"].ToString()));
|
||||
}
|
||||
get => typeof(FFMpegCore.FFMpeg).Assembly.GetName().Version.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +93,7 @@ namespace SpineViewer.Dialogs
|
||||
var properties = selectedObject.GetType().GetProperties();
|
||||
var result = string.Join(Environment.NewLine, properties.Select(p => $"{p.Name}\t{p.GetValue(selectedObject)?.ToString()}"));
|
||||
Clipboard.SetText(result);
|
||||
MessageBox.Info("已复制");
|
||||
MessagePopup.Info("已复制", Properties.Resources.msgBoxInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,16 +117,16 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>187, 20</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>89</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="button_Copy.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>214, 325</value>
|
||||
</data>
|
||||
<data name="button_Copy.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>155, 30</value>
|
||||
</data>
|
||||
<data name="button_Copy.Text" xml:space="preserve">
|
||||
<value>Copy to Clipboard</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3273,4 +3273,7 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Diagnostic Information</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,7 +117,36 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Copy.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>None</value>
|
||||
</data>
|
||||
<data name=">>button_Copy.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>panel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="button_Copy.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>124, 30</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="propertyGrid.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 2</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3264,4 +3293,140 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name=">>panel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>button_Copy.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Copy.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 8, 2, 2</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>诊断信息</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="button_Copy.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="button_Copy" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="propertyGrid" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Copy.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid.Name" xml:space="preserve">
|
||||
<value>propertyGrid</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>panel1.Name" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>655, 377</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>DiagnosticsDialog</value>
|
||||
</data>
|
||||
<data name="propertyGrid.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_Copy.Text" xml:space="preserve">
|
||||
<value>复制到剪贴板</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>655, 377</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="propertyGrid.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>579, 313</value>
|
||||
</data>
|
||||
<data name=">>button_Copy.Name" xml:space="preserve">
|
||||
<value>button_Copy</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>button_Copy.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name="button_Copy.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>229, 325</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Copy.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>7, 0, 7, 0</value>
|
||||
</data>
|
||||
<data name="propertyGrid.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>36, 12, 36, 8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>583, 357</value>
|
||||
</data>
|
||||
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>panel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>36, 12</value>
|
||||
</data>
|
||||
<metadata name="$this.Language" type="System.Globalization.CultureInfo, System.Private.CoreLib, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>en</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
112
SpineViewer/Dialogs/ExportDialog.Designer.cs
generated
Normal file
112
SpineViewer/Dialogs/ExportDialog.Designer.cs
generated
Normal file
@@ -0,0 +1,112 @@
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
partial class ExportDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExportDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
propertyGrid_ExportArgs = new PropertyGrid();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(propertyGrid_ExportArgs, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 1);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// propertyGrid_ExportArgs
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_ExportArgs, "propertyGrid_ExportArgs");
|
||||
propertyGrid_ExportArgs.Name = "propertyGrid_ExportArgs";
|
||||
propertyGrid_ExportArgs.PropertySort = PropertySort.Categorized;
|
||||
propertyGrid_ExportArgs.ToolbarVisible = false;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel2, "tableLayoutPanel2");
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
resources.ApplyResources(button_Ok, "button_Ok");
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
resources.ApplyResources(button_Cancel, "button_Cancel");
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// ExportDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
Controls.Add(panel1);
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ExportDialog";
|
||||
ShowInTaskbar = false;
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
private Button button_Cancel;
|
||||
private PropertyGrid propertyGrid_ExportArgs;
|
||||
}
|
||||
}
|
||||
79
SpineViewer/Dialogs/ExportDialog.cs
Normal file
79
SpineViewer/Dialogs/ExportDialog.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using SpineViewer.Spine.SpineExporter;
|
||||
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ExportDialog : Form
|
||||
{
|
||||
private readonly ExporterProperty wrapper;
|
||||
|
||||
public ExportDialog(ExporterProperty wrapper)
|
||||
{
|
||||
InitializeComponent();
|
||||
this.wrapper = wrapper;
|
||||
propertyGrid_ExportArgs.SelectedObject = wrapper;
|
||||
|
||||
#region XXX: 通过反射默认高亮指定的项
|
||||
var categories = propertyGrid_ExportArgs.SelectedGridItem?.Parent?.Parent?.GridItems;
|
||||
if (categories is null) return;
|
||||
|
||||
foreach (var category in categories)
|
||||
{
|
||||
// 查找 "导出" 分组
|
||||
if (category == null) continue;
|
||||
PropertyInfo? labelProp = category.GetType().GetProperty("Label", BindingFlags.Instance | BindingFlags.Public);
|
||||
if (labelProp == null) continue;
|
||||
string? label = labelProp.GetValue(category) as string;
|
||||
if (label != "[0] 导出") continue;
|
||||
|
||||
// 获取该分组下的所有属性项
|
||||
PropertyInfo? gridItemsProp = category.GetType().GetProperty("GridItems", BindingFlags.Instance | BindingFlags.Public);
|
||||
if (gridItemsProp == null) continue;
|
||||
var gridItemsObj = gridItemsProp.GetValue(category);
|
||||
if (gridItemsObj is not IEnumerable gridItems) continue;
|
||||
|
||||
foreach (object item in gridItems)
|
||||
{
|
||||
if (item == null) continue;
|
||||
PropertyInfo? propDescProp = item.GetType().GetProperty("PropertyDescriptor", BindingFlags.Instance | BindingFlags.Public);
|
||||
if (propDescProp == null) continue;
|
||||
var propDesc = propDescProp.GetValue(item) as PropertyDescriptor;
|
||||
if (propDesc == null) continue;
|
||||
if (propDesc.Name == "OutputDir")
|
||||
{
|
||||
|
||||
if (item is GridItem gridItem)
|
||||
propertyGrid_ExportArgs.SelectedGridItem = gridItem; // 找到后,将此项设为选中项
|
||||
else
|
||||
propertyGrid_ExportArgs.SelectedGridItem = (GridItem)item; // 如果转换失败,则尝试直接赋值
|
||||
}
|
||||
return; // 设置成功后退出
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
private void button_Ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (wrapper.Exporter.Validate() is string error)
|
||||
{
|
||||
MessagePopup.Info(error, Properties.Resources.parameterError);
|
||||
return;
|
||||
}
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void button_Cancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,9 +117,12 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="folderBrowserDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<data name="button_Ok.Text" xml:space="preserve">
|
||||
<value>Confirm</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
@@ -3267,4 +3270,7 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Export Parameters</value>
|
||||
</data>
|
||||
</root>
|
||||
3495
SpineViewer/Dialogs/ExportDialog.resx
Normal file
3495
SpineViewer/Dialogs/ExportDialog.resx
Normal file
File diff suppressed because it is too large
Load Diff
270
SpineViewer/Dialogs/ExportPngDialog.Designer.cs
generated
270
SpineViewer/Dialogs/ExportPngDialog.Designer.cs
generated
@@ -1,270 +0,0 @@
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
partial class ExportPngDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExportPngDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label4 = new Label();
|
||||
label1 = new Label();
|
||||
label2 = new Label();
|
||||
label3 = new Label();
|
||||
textBox_OutputDir = new TextBox();
|
||||
button_SelectOutputDir = new Button();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
numericUpDown_Duration = new NumericUpDown();
|
||||
numericUpDown_Fps = new NumericUpDown();
|
||||
folderBrowserDialog = new FolderBrowserDialog();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)numericUpDown_Duration).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)numericUpDown_Fps).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(0, 0);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(50, 15, 50, 10);
|
||||
panel1.Size = new Size(919, 276);
|
||||
panel1.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.AutoSize = true;
|
||||
tableLayoutPanel1.ColumnCount = 4;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label1, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(label2, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 3);
|
||||
tableLayoutPanel1.Controls.Add(textBox_OutputDir, 1, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectOutputDir, 3, 1);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 4);
|
||||
tableLayoutPanel1.Controls.Add(numericUpDown_Duration, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(numericUpDown_Fps, 1, 3);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(50, 15);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 5;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(819, 251);
|
||||
tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.AutoSize = true;
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Dock = DockStyle.Fill;
|
||||
label4.Location = new Point(15, 15);
|
||||
label4.Margin = new Padding(15);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new Size(789, 24);
|
||||
label4.TabIndex = 11;
|
||||
label4.Text = "说明:时长不足一帧时仅导出第一帧";
|
||||
label4.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Anchor = AnchorStyles.Right;
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new Point(3, 62);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(104, 24);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "输出文件夹:";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.Anchor = AnchorStyles.Right;
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new Point(57, 100);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new Size(50, 24);
|
||||
label2.TabIndex = 1;
|
||||
label2.Text = "时长:";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Anchor = AnchorStyles.Right;
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new Point(57, 136);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new Size(50, 24);
|
||||
label3.TabIndex = 2;
|
||||
label3.Text = "帧率:";
|
||||
//
|
||||
// textBox_OutputDir
|
||||
//
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_OutputDir, 2);
|
||||
textBox_OutputDir.Dock = DockStyle.Fill;
|
||||
textBox_OutputDir.Location = new Point(113, 57);
|
||||
textBox_OutputDir.Name = "textBox_OutputDir";
|
||||
textBox_OutputDir.Size = new Size(664, 30);
|
||||
textBox_OutputDir.TabIndex = 3;
|
||||
//
|
||||
// button_SelectOutputDir
|
||||
//
|
||||
button_SelectOutputDir.AutoSize = true;
|
||||
button_SelectOutputDir.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_SelectOutputDir.Location = new Point(783, 57);
|
||||
button_SelectOutputDir.Name = "button_SelectOutputDir";
|
||||
button_SelectOutputDir.Size = new Size(32, 34);
|
||||
button_SelectOutputDir.TabIndex = 5;
|
||||
button_SelectOutputDir.Text = "...";
|
||||
button_SelectOutputDir.UseVisualStyleBackColor = true;
|
||||
button_SelectOutputDir.Click += button_SelectOutputDir_Click;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
tableLayoutPanel2.AutoSize = true;
|
||||
tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
tableLayoutPanel2.ColumnCount = 2;
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Dock = DockStyle.Bottom;
|
||||
tableLayoutPanel2.Location = new Point(3, 208);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
tableLayoutPanel2.RowCount = 1;
|
||||
tableLayoutPanel2.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel2.Size = new Size(813, 40);
|
||||
tableLayoutPanel2.TabIndex = 10;
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
button_Ok.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
button_Ok.Location = new Point(264, 3);
|
||||
button_Ok.Margin = new Padding(3, 3, 30, 3);
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.Size = new Size(112, 34);
|
||||
button_Ok.TabIndex = 7;
|
||||
button_Ok.Text = "确认";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
button_Cancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
|
||||
button_Cancel.Location = new Point(436, 3);
|
||||
button_Cancel.Margin = new Padding(30, 3, 3, 3);
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.Size = new Size(112, 34);
|
||||
button_Cancel.TabIndex = 8;
|
||||
button_Cancel.Text = "取消";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// numericUpDown_Duration
|
||||
//
|
||||
numericUpDown_Duration.Anchor = AnchorStyles.Left;
|
||||
numericUpDown_Duration.DecimalPlaces = 3;
|
||||
numericUpDown_Duration.Location = new Point(113, 97);
|
||||
numericUpDown_Duration.Maximum = new decimal(new int[] { 300, 0, 0, 0 });
|
||||
numericUpDown_Duration.Name = "numericUpDown_Duration";
|
||||
numericUpDown_Duration.Size = new Size(180, 30);
|
||||
numericUpDown_Duration.TabIndex = 12;
|
||||
numericUpDown_Duration.TextAlign = HorizontalAlignment.Right;
|
||||
numericUpDown_Duration.Value = new decimal(new int[] { 1, 0, 0, 0 });
|
||||
//
|
||||
// numericUpDown_Fps
|
||||
//
|
||||
numericUpDown_Fps.Anchor = AnchorStyles.Left;
|
||||
numericUpDown_Fps.Location = new Point(113, 133);
|
||||
numericUpDown_Fps.Maximum = new decimal(new int[] { 300, 0, 0, 0 });
|
||||
numericUpDown_Fps.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||
numericUpDown_Fps.Name = "numericUpDown_Fps";
|
||||
numericUpDown_Fps.Size = new Size(180, 30);
|
||||
numericUpDown_Fps.TabIndex = 13;
|
||||
numericUpDown_Fps.TextAlign = HorizontalAlignment.Right;
|
||||
numericUpDown_Fps.Value = new decimal(new int[] { 60, 0, 0, 0 });
|
||||
//
|
||||
// folderBrowserDialog
|
||||
//
|
||||
folderBrowserDialog.AddToRecent = false;
|
||||
//
|
||||
// ExportPngDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
ClientSize = new Size(919, 276);
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ExportPngDialog";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "导出PNG序列";
|
||||
Load += ExportPngDialog_Load;
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)numericUpDown_Duration).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)numericUpDown_Fps).EndInit();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Label label4;
|
||||
private Label label1;
|
||||
private Label label2;
|
||||
private Label label3;
|
||||
private TextBox textBox_OutputDir;
|
||||
private Button button_SelectOutputDir;
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
private Button button_Cancel;
|
||||
private NumericUpDown numericUpDown_Duration;
|
||||
private NumericUpDown numericUpDown_Fps;
|
||||
private FolderBrowserDialog folderBrowserDialog;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ExportPngDialog : Form
|
||||
{
|
||||
// TODO: 该对话框要合并到统一的导出参数对话框
|
||||
// TODO: 使用结果包装类
|
||||
public string OutputDir { get; private set; }
|
||||
public float Duration { get; private set; }
|
||||
public uint Fps { get; private set; }
|
||||
|
||||
public ExportPngDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void ExportPngDialog_Load(object sender, EventArgs e)
|
||||
{
|
||||
button_SelectOutputDir_Click(sender, e);
|
||||
}
|
||||
|
||||
private void button_SelectOutputDir_Click(object sender, EventArgs e)
|
||||
{
|
||||
folderBrowserDialog.InitialDirectory = textBox_OutputDir.Text;
|
||||
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
textBox_OutputDir.Text = Path.GetFullPath(folderBrowserDialog.SelectedPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void button_Ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
var outputDir = textBox_OutputDir.Text;
|
||||
if (File.Exists(outputDir))
|
||||
{
|
||||
MessageBox.Info("输出文件夹无效");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(outputDir))
|
||||
{
|
||||
if (MessageBox.Quest($"文件夹 {outputDir} 不存在,是否创建?") != DialogResult.OK)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(outputDir);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Logger.Error(ex.ToString());
|
||||
MessageBox.Error(ex.ToString(), "文件夹创建失败");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
OutputDir = Path.GetFullPath(outputDir);
|
||||
Duration = (float)numericUpDown_Duration.Value;
|
||||
Fps = (uint)numericUpDown_Fps.Value;
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void button_Cancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
}
|
||||
223
SpineViewer/Dialogs/ExportPreviewDialog.Designer.cs
generated
223
SpineViewer/Dialogs/ExportPreviewDialog.Designer.cs
generated
@@ -1,223 +0,0 @@
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
partial class ExportPreviewDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExportPreviewDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
propertyGrid = new PropertyGrid();
|
||||
label4 = new Label();
|
||||
label1 = new Label();
|
||||
textBox_OutputDir = new TextBox();
|
||||
button_SelectOutputDir = new Button();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
folderBrowserDialog = new FolderBrowserDialog();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(0, 0);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(50, 15, 50, 10);
|
||||
panel1.Size = new Size(914, 482);
|
||||
panel1.TabIndex = 2;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.AutoSize = true;
|
||||
tableLayoutPanel1.ColumnCount = 4;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.Controls.Add(propertyGrid, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label1, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(textBox_OutputDir, 1, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectOutputDir, 3, 1);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 3);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(50, 15);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 4;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(814, 457);
|
||||
tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// propertyGrid
|
||||
//
|
||||
tableLayoutPanel1.SetColumnSpan(propertyGrid, 4);
|
||||
propertyGrid.Dock = DockStyle.Fill;
|
||||
propertyGrid.HelpVisible = false;
|
||||
propertyGrid.Location = new Point(3, 97);
|
||||
propertyGrid.Name = "propertyGrid";
|
||||
propertyGrid.Size = new Size(808, 284);
|
||||
propertyGrid.TabIndex = 1;
|
||||
propertyGrid.ToolbarVisible = false;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.AutoSize = true;
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Dock = DockStyle.Fill;
|
||||
label4.Location = new Point(15, 15);
|
||||
label4.Margin = new Padding(15);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new Size(784, 24);
|
||||
label4.TabIndex = 11;
|
||||
label4.Text = "说明:输出文件夹为可选项,留空则将预览图输出到每个骨骼文件所在目录";
|
||||
label4.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Anchor = AnchorStyles.Right;
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new Point(3, 62);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(104, 24);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "输出文件夹:";
|
||||
//
|
||||
// textBox_OutputDir
|
||||
//
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_OutputDir, 2);
|
||||
textBox_OutputDir.Dock = DockStyle.Fill;
|
||||
textBox_OutputDir.Location = new Point(113, 57);
|
||||
textBox_OutputDir.Name = "textBox_OutputDir";
|
||||
textBox_OutputDir.Size = new Size(660, 30);
|
||||
textBox_OutputDir.TabIndex = 3;
|
||||
//
|
||||
// button_SelectOutputDir
|
||||
//
|
||||
button_SelectOutputDir.AutoSize = true;
|
||||
button_SelectOutputDir.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_SelectOutputDir.Location = new Point(779, 57);
|
||||
button_SelectOutputDir.Name = "button_SelectOutputDir";
|
||||
button_SelectOutputDir.Size = new Size(32, 34);
|
||||
button_SelectOutputDir.TabIndex = 5;
|
||||
button_SelectOutputDir.Text = "...";
|
||||
button_SelectOutputDir.UseVisualStyleBackColor = true;
|
||||
button_SelectOutputDir.Click += button_SelectOutputDir_Click;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
tableLayoutPanel2.AutoSize = true;
|
||||
tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
tableLayoutPanel2.ColumnCount = 2;
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Dock = DockStyle.Bottom;
|
||||
tableLayoutPanel2.Location = new Point(3, 414);
|
||||
tableLayoutPanel2.Margin = new Padding(3, 30, 3, 3);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
tableLayoutPanel2.RowCount = 1;
|
||||
tableLayoutPanel2.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel2.Size = new Size(808, 40);
|
||||
tableLayoutPanel2.TabIndex = 10;
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
button_Ok.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
button_Ok.Location = new Point(262, 3);
|
||||
button_Ok.Margin = new Padding(3, 3, 30, 3);
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.Size = new Size(112, 34);
|
||||
button_Ok.TabIndex = 7;
|
||||
button_Ok.Text = "确认";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
button_Cancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
|
||||
button_Cancel.Location = new Point(434, 3);
|
||||
button_Cancel.Margin = new Padding(30, 3, 3, 3);
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.Size = new Size(112, 34);
|
||||
button_Cancel.TabIndex = 8;
|
||||
button_Cancel.Text = "取消";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// folderBrowserDialog
|
||||
//
|
||||
folderBrowserDialog.AddToRecent = false;
|
||||
//
|
||||
// ExportPreviewDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
ClientSize = new Size(914, 482);
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ExportPreviewDialog";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "导出预览图";
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Label label4;
|
||||
private Label label1;
|
||||
private TextBox textBox_OutputDir;
|
||||
private Button button_SelectOutputDir;
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
private Button button_Cancel;
|
||||
private FolderBrowserDialog folderBrowserDialog;
|
||||
private PropertyGrid propertyGrid;
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ExportPreviewDialog: Form
|
||||
{
|
||||
/// <summary>
|
||||
/// 对话框结果
|
||||
/// </summary>
|
||||
public readonly ExportPreviewDialogResult Result = new();
|
||||
|
||||
public ExportPreviewDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
propertyGrid.SelectedObject = Result;
|
||||
}
|
||||
|
||||
private void button_SelectOutputDir_Click(object sender, EventArgs e)
|
||||
{
|
||||
folderBrowserDialog.InitialDirectory = textBox_OutputDir.Text;
|
||||
if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
textBox_OutputDir.Text = Path.GetFullPath(folderBrowserDialog.SelectedPath);
|
||||
}
|
||||
|
||||
private void button_Ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
var outputDir = textBox_OutputDir.Text;
|
||||
if (string.IsNullOrEmpty(outputDir))
|
||||
{
|
||||
Result.OutputDir = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (File.Exists(outputDir))
|
||||
{
|
||||
MessageBox.Info("输出文件夹无效");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(outputDir))
|
||||
{
|
||||
if (MessageBox.Quest($"文件夹 {outputDir} 不存在,是否创建?") != DialogResult.OK)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(outputDir);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Logger.Error(ex.ToString());
|
||||
MessageBox.Error(ex.ToString(), "文件夹创建失败");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Result.OutputDir = Path.GetFullPath(outputDir);
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void button_Cancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
public class ExportPreviewDialogResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 输出路径
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
public string? OutputDir { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// 预览图格式
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(ImageFormatConverter))]
|
||||
[Category("导出参数"), DisplayName("预览图格式")]
|
||||
public ImageFormat ImageFormat
|
||||
{
|
||||
get => imageFormat;
|
||||
set
|
||||
{
|
||||
if (value == ImageFormat.MemoryBmp) value = ImageFormat.Bmp;
|
||||
imageFormat = value;
|
||||
}
|
||||
}
|
||||
private ImageFormat imageFormat = ImageFormat.Png;
|
||||
|
||||
/// <summary>
|
||||
/// 预览图分辨率
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(SizeConverter))]
|
||||
[Category("导出参数"), DisplayName("分辨率")]
|
||||
public Size Resolution
|
||||
{
|
||||
get => resolution;
|
||||
set
|
||||
{
|
||||
if (value.Width <= 0) value.Width = 128;
|
||||
if (value.Height <= 0) value.Height = 128;
|
||||
resolution = value;
|
||||
}
|
||||
}
|
||||
private Size resolution = new(512, 512);
|
||||
|
||||
/// <summary>
|
||||
/// 四周填充像素值
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(PaddingConverter))]
|
||||
[Category("导出参数"), DisplayName("四周填充像素值")]
|
||||
public Padding Padding
|
||||
{
|
||||
get => padding;
|
||||
set
|
||||
{
|
||||
if (value.Left <= 0) value.Left = 10;
|
||||
if (value.Right <= 0) value.Right = 10;
|
||||
if (value.Top <= 0) value.Top = 10;
|
||||
if (value.Bottom <= 0) value.Bottom = 10;
|
||||
padding = value;
|
||||
}
|
||||
}
|
||||
private Padding padding = new(1);
|
||||
|
||||
/// <summary>
|
||||
/// DPI
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(SizeFConverter))]
|
||||
[Category("导出参数"), DisplayName("DPI")]
|
||||
public SizeF DPI
|
||||
{
|
||||
get => dpi;
|
||||
set
|
||||
{
|
||||
if (value.Width <= 0) value.Width = 144;
|
||||
if (value.Height <= 0) value.Height = 144;
|
||||
dpi = value;
|
||||
}
|
||||
}
|
||||
private SizeF dpi = new(144, 144);
|
||||
}
|
||||
|
||||
}
|
||||
408
SpineViewer/Dialogs/OpenSpineDialog.Designer.cs
generated
408
SpineViewer/Dialogs/OpenSpineDialog.Designer.cs
generated
@@ -20,256 +20,170 @@
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OpenSpineDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label4 = new Label();
|
||||
label1 = new Label();
|
||||
label2 = new Label();
|
||||
label3 = new Label();
|
||||
textBox_SkelPath = new TextBox();
|
||||
button_SelectSkel = new Button();
|
||||
button_SelectAtlas = new Button();
|
||||
comboBox_Version = new ComboBox();
|
||||
textBox_AtlasPath = new TextBox();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
openFileDialog_Skel = new OpenFileDialog();
|
||||
openFileDialog_Atlas = new OpenFileDialog();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(0, 0);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(50, 15, 50, 10);
|
||||
panel1.Size = new Size(907, 286);
|
||||
panel1.TabIndex = 0;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.AutoSize = true;
|
||||
tableLayoutPanel1.ColumnCount = 4;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label1, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(label2, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 3);
|
||||
tableLayoutPanel1.Controls.Add(textBox_SkelPath, 1, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectSkel, 3, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectAtlas, 3, 2);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_Version, 1, 3);
|
||||
tableLayoutPanel1.Controls.Add(textBox_AtlasPath, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 4);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(50, 15);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 5;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(807, 261);
|
||||
tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.AutoSize = true;
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Dock = DockStyle.Fill;
|
||||
label4.Location = new Point(15, 15);
|
||||
label4.Margin = new Padding(15);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new Size(777, 24);
|
||||
label4.TabIndex = 11;
|
||||
label4.Text = "说明:如果没有选择atlas,则会自动读取与skel同目录下同名的atlas文件";
|
||||
label4.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Anchor = AnchorStyles.Right;
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new Point(10, 62);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(119, 24);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "skel文件路径:";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.Anchor = AnchorStyles.Right;
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new Point(3, 102);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new Size(126, 24);
|
||||
label2.TabIndex = 1;
|
||||
label2.Text = "atlas文件路径:";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Anchor = AnchorStyles.Right;
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new Point(79, 141);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new Size(50, 24);
|
||||
label3.TabIndex = 2;
|
||||
label3.Text = "版本:";
|
||||
//
|
||||
// textBox_SkelPath
|
||||
//
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_SkelPath, 2);
|
||||
textBox_SkelPath.Dock = DockStyle.Fill;
|
||||
textBox_SkelPath.Location = new Point(135, 57);
|
||||
textBox_SkelPath.Name = "textBox_SkelPath";
|
||||
textBox_SkelPath.Size = new Size(630, 30);
|
||||
textBox_SkelPath.TabIndex = 3;
|
||||
//
|
||||
// button_SelectSkel
|
||||
//
|
||||
button_SelectSkel.AutoSize = true;
|
||||
button_SelectSkel.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_SelectSkel.Location = new Point(771, 57);
|
||||
button_SelectSkel.Name = "button_SelectSkel";
|
||||
button_SelectSkel.Size = new Size(32, 34);
|
||||
button_SelectSkel.TabIndex = 5;
|
||||
button_SelectSkel.Text = "...";
|
||||
button_SelectSkel.UseVisualStyleBackColor = true;
|
||||
button_SelectSkel.Click += button_SelectSkel_Click;
|
||||
//
|
||||
// button_SelectAtlas
|
||||
//
|
||||
button_SelectAtlas.AutoSize = true;
|
||||
button_SelectAtlas.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_SelectAtlas.Location = new Point(771, 97);
|
||||
button_SelectAtlas.Name = "button_SelectAtlas";
|
||||
button_SelectAtlas.Size = new Size(32, 34);
|
||||
button_SelectAtlas.TabIndex = 6;
|
||||
button_SelectAtlas.Text = "...";
|
||||
button_SelectAtlas.UseVisualStyleBackColor = true;
|
||||
button_SelectAtlas.Click += button_SelectAtlas_Click;
|
||||
//
|
||||
// comboBox_Version
|
||||
//
|
||||
comboBox_Version.Anchor = AnchorStyles.Left;
|
||||
comboBox_Version.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_Version.FormattingEnabled = true;
|
||||
comboBox_Version.Location = new Point(135, 137);
|
||||
comboBox_Version.Name = "comboBox_Version";
|
||||
comboBox_Version.Size = new Size(182, 32);
|
||||
comboBox_Version.Sorted = true;
|
||||
comboBox_Version.TabIndex = 9;
|
||||
//
|
||||
// textBox_AtlasPath
|
||||
//
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_AtlasPath, 2);
|
||||
textBox_AtlasPath.Dock = DockStyle.Fill;
|
||||
textBox_AtlasPath.Location = new Point(135, 97);
|
||||
textBox_AtlasPath.Name = "textBox_AtlasPath";
|
||||
textBox_AtlasPath.Size = new Size(630, 30);
|
||||
textBox_AtlasPath.TabIndex = 4;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
tableLayoutPanel2.AutoSize = true;
|
||||
tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
tableLayoutPanel2.ColumnCount = 2;
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Dock = DockStyle.Bottom;
|
||||
tableLayoutPanel2.Location = new Point(3, 218);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
tableLayoutPanel2.RowCount = 1;
|
||||
tableLayoutPanel2.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel2.Size = new Size(801, 40);
|
||||
tableLayoutPanel2.TabIndex = 10;
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
button_Ok.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
button_Ok.Location = new Point(258, 3);
|
||||
button_Ok.Margin = new Padding(3, 3, 30, 3);
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.Size = new Size(112, 34);
|
||||
button_Ok.TabIndex = 7;
|
||||
button_Ok.Text = "确认";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
button_Cancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
|
||||
button_Cancel.Location = new Point(430, 3);
|
||||
button_Cancel.Margin = new Padding(30, 3, 3, 3);
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.Size = new Size(112, 34);
|
||||
button_Cancel.TabIndex = 8;
|
||||
button_Cancel.Text = "取消";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// openFileDialog_Skel
|
||||
//
|
||||
openFileDialog_Skel.AddExtension = false;
|
||||
openFileDialog_Skel.AddToRecent = false;
|
||||
openFileDialog_Skel.Filter = "skel 文件 (*.skel; *.json)|*.skel;*.json|二进制文件 (*.skel)|*.skel|文本文件 (*.json)|*.json|所有文件 (*.*)|*.*";
|
||||
openFileDialog_Skel.Title = "选择skel文件";
|
||||
//
|
||||
// openFileDialog_Atlas
|
||||
//
|
||||
openFileDialog_Atlas.AddExtension = false;
|
||||
openFileDialog_Atlas.AddToRecent = false;
|
||||
openFileDialog_Atlas.Filter = "atlas 文件 (*.atlas)|*.atlas|所有文件 (*.*)|*.*";
|
||||
openFileDialog_Atlas.Title = "选择atlas文件";
|
||||
//
|
||||
// OpenSpineDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
ClientSize = new Size(907, 286);
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "OpenSpineDialog";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "打开骨骼";
|
||||
Load += OpenSpineDialog_Load;
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OpenSpineDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label4 = new Label();
|
||||
label1 = new Label();
|
||||
label2 = new Label();
|
||||
label3 = new Label();
|
||||
textBox_SkelPath = new TextBox();
|
||||
button_SelectSkel = new Button();
|
||||
button_SelectAtlas = new Button();
|
||||
comboBox_Version = new ComboBox();
|
||||
textBox_AtlasPath = new TextBox();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
openFileDialog_Skel = new OpenFileDialog();
|
||||
openFileDialog_Atlas = new OpenFileDialog();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label1, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(label2, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 3);
|
||||
tableLayoutPanel1.Controls.Add(textBox_SkelPath, 1, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectSkel, 3, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectAtlas, 3, 2);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_Version, 1, 3);
|
||||
tableLayoutPanel1.Controls.Add(textBox_AtlasPath, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 4);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
resources.ApplyResources(label4, "label4");
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Name = "label4";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
resources.ApplyResources(label1, "label1");
|
||||
label1.Name = "label1";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
resources.ApplyResources(label2, "label2");
|
||||
label2.Name = "label2";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(label3, "label3");
|
||||
label3.Name = "label3";
|
||||
//
|
||||
// textBox_SkelPath
|
||||
//
|
||||
resources.ApplyResources(textBox_SkelPath, "textBox_SkelPath");
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_SkelPath, 2);
|
||||
textBox_SkelPath.Name = "textBox_SkelPath";
|
||||
//
|
||||
// button_SelectSkel
|
||||
//
|
||||
resources.ApplyResources(button_SelectSkel, "button_SelectSkel");
|
||||
button_SelectSkel.Name = "button_SelectSkel";
|
||||
button_SelectSkel.UseVisualStyleBackColor = true;
|
||||
button_SelectSkel.Click += button_SelectSkel_Click;
|
||||
//
|
||||
// button_SelectAtlas
|
||||
//
|
||||
resources.ApplyResources(button_SelectAtlas, "button_SelectAtlas");
|
||||
button_SelectAtlas.Name = "button_SelectAtlas";
|
||||
button_SelectAtlas.UseVisualStyleBackColor = true;
|
||||
button_SelectAtlas.Click += button_SelectAtlas_Click;
|
||||
//
|
||||
// comboBox_Version
|
||||
//
|
||||
resources.ApplyResources(comboBox_Version, "comboBox_Version");
|
||||
comboBox_Version.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_Version.FormattingEnabled = true;
|
||||
comboBox_Version.Name = "comboBox_Version";
|
||||
comboBox_Version.Sorted = true;
|
||||
//
|
||||
// textBox_AtlasPath
|
||||
//
|
||||
resources.ApplyResources(textBox_AtlasPath, "textBox_AtlasPath");
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_AtlasPath, 2);
|
||||
textBox_AtlasPath.Name = "textBox_AtlasPath";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel2, "tableLayoutPanel2");
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
resources.ApplyResources(button_Ok, "button_Ok");
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
resources.ApplyResources(button_Cancel, "button_Cancel");
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// openFileDialog_Skel
|
||||
//
|
||||
openFileDialog_Skel.AddExtension = false;
|
||||
openFileDialog_Skel.AddToRecent = false;
|
||||
resources.ApplyResources(openFileDialog_Skel, "openFileDialog_Skel");
|
||||
//
|
||||
// openFileDialog_Atlas
|
||||
//
|
||||
openFileDialog_Atlas.AddExtension = false;
|
||||
openFileDialog_Atlas.AddToRecent = false;
|
||||
resources.ApplyResources(openFileDialog_Atlas, "openFileDialog_Atlas");
|
||||
//
|
||||
// OpenSpineDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "OpenSpineDialog";
|
||||
ShowInTaskbar = false;
|
||||
Load += OpenSpineDialog_Load;
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Label label1;
|
||||
private Label label2;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SpineViewer.Spine;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -20,10 +21,10 @@ namespace SpineViewer.Dialogs
|
||||
public OpenSpineDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
comboBox_Version.DataSource = VersionHelper.Names.ToList();
|
||||
comboBox_Version.DataSource = SpineUtils.Names.ToList();
|
||||
comboBox_Version.DisplayMember = "Value";
|
||||
comboBox_Version.ValueMember = "Key";
|
||||
comboBox_Version.SelectedValue = Spine.Version.Auto;
|
||||
comboBox_Version.SelectedValue = SpineVersion.Auto;
|
||||
}
|
||||
|
||||
private void OpenSpineDialog_Load(object sender, EventArgs e)
|
||||
@@ -53,11 +54,11 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
var skelPath = textBox_SkelPath.Text;
|
||||
var atlasPath = textBox_AtlasPath.Text;
|
||||
var version = (Spine.Version)comboBox_Version.SelectedValue;
|
||||
var version = (SpineVersion)comboBox_Version.SelectedValue;
|
||||
|
||||
if (!File.Exists(skelPath))
|
||||
{
|
||||
MessageBox.Info($"{skelPath}", "skel文件不存在");
|
||||
MessagePopup.Info($"{skelPath}", Properties.Resources.skelNotExist);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -65,13 +66,13 @@ namespace SpineViewer.Dialogs
|
||||
skelPath = Path.GetFullPath(skelPath);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(atlasPath))
|
||||
if (string.IsNullOrWhiteSpace(atlasPath))
|
||||
{
|
||||
atlasPath = null;
|
||||
}
|
||||
else if (!File.Exists(atlasPath))
|
||||
{
|
||||
MessageBox.Info($"{atlasPath}", "atlas文件不存在");
|
||||
MessagePopup.Info($"{atlasPath}", Properties.Resources.atlasNotExist);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -79,9 +80,9 @@ namespace SpineViewer.Dialogs
|
||||
atlasPath = Path.GetFullPath(atlasPath);
|
||||
}
|
||||
|
||||
if (version != Spine.Version.Auto && !Spine.Spine.ImplementedVersions.Contains(version))
|
||||
if (version != SpineVersion.Auto && !Spine.SpineObject.HasImplementation(version))
|
||||
{
|
||||
MessageBox.Info($"{version.GetName()} 版本尚未实现(咕咕咕~)");
|
||||
MessagePopup.Info($"{version.GetName()} 版本尚未实现(咕咕咕~)", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -98,12 +99,12 @@ namespace SpineViewer.Dialogs
|
||||
/// <summary>
|
||||
/// 打开骨骼对话框结果
|
||||
/// </summary>
|
||||
public class OpenSpineDialogResult(Spine.Version version, string skelPath, string? atlasPath = null)
|
||||
public class OpenSpineDialogResult(SpineVersion version, string skelPath, string? atlasPath = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
public Spine.Version Version => version;
|
||||
public SpineVersion Version => version;
|
||||
|
||||
/// <summary>
|
||||
/// skel 文件路径
|
||||
|
||||
3324
SpineViewer/Dialogs/OpenSpineDialog.en.resx
Normal file
3324
SpineViewer/Dialogs/OpenSpineDialog.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -117,13 +117,232 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="openFileDialog_Skel.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>58, 25</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog_Atlas.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>349, 29</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_SelectSkel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label3.Name" xml:space="preserve">
|
||||
<value>label3</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Cancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left</value>
|
||||
</data>
|
||||
<data name=">>button_SelectAtlas.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>textBox_AtlasPath.ZOrder" xml:space="preserve">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label4" Row="0" RowSpan="1" Column="0" ColumnSpan="4" /><Control Name="label1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label2" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label3" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textBox_SkelPath" Row="1" RowSpan="1" Column="1" ColumnSpan="2" /><Control Name="button_SelectSkel" Row="1" RowSpan="1" Column="3" ColumnSpan="1" /><Control Name="button_SelectAtlas" Row="2" RowSpan="1" Column="3" ColumnSpan="1" /><Control Name="comboBox_Version" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textBox_AtlasPath" Row="2" RowSpan="1" Column="1" ColumnSpan="2" /><Control Name="tableLayoutPanel2" Row="4" RowSpan="1" Column="0" ColumnSpan="4" /></Controls><Columns Styles="AutoSize,0,Percent,50,Percent,50,AutoSize,0" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="label2.Text" xml:space="preserve">
|
||||
<value>atlas文件路径:</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel2.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>label3.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>skel文件路径:</value>
|
||||
</data>
|
||||
<data name=">>button_SelectSkel.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name="button_Ok.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 22, 2</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="textBox_SkelPath.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>109, 46</value>
|
||||
</data>
|
||||
<data name="label4.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>label1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button_SelectAtlas.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name=">>label3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label4.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="textBox_SkelPath.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>textBox_AtlasPath.Name" xml:space="preserve">
|
||||
<value>textBox_AtlasPath</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>314, 2</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>133, 28</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Atlas.Filter" xml:space="preserve">
|
||||
<value>所有文件 (*.*)|*.*|atlas 文件 (*.atlas)|*.atlas</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>button_SelectSkel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.Text" xml:space="preserve">
|
||||
<value>...</value>
|
||||
</data>
|
||||
<data name=">>panel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>panel1.Name" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Skel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 85</value>
|
||||
</data>
|
||||
<data name=">>textBox_SkelPath.Name" xml:space="preserve">
|
||||
<value>textBox_SkelPath</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label2.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Atlas.Name" xml:space="preserve">
|
||||
<value>openFileDialog_Atlas</value>
|
||||
</data>
|
||||
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>566, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 184</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label4.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>557, 80</value>
|
||||
</data>
|
||||
<data name="button_Ok.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="label3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name=">>panel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label3.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Name" xml:space="preserve">
|
||||
<value>button_Ok</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="label1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Title" xml:space="preserve">
|
||||
<value>选择skel文件</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="textBox_SkelPath.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="label3.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>button_SelectSkel.Name" xml:space="preserve">
|
||||
<value>button_SelectSkel</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>36, 12, 36, 8</value>
|
||||
</data>
|
||||
<data name=">>textBox_SkelPath.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>444, 27</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.RowCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>textBox_SkelPath.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>textBox_SkelPath.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>588, 218</value>
|
||||
</data>
|
||||
<data name="button_Ok.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>189, 2</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3270,4 +3489,292 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>584, 32</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>22, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>版本:</value>
|
||||
</data>
|
||||
<data name=">>label1.Name" xml:space="preserve">
|
||||
<value>label1</value>
|
||||
</data>
|
||||
<data name="button_Ok.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name=">>label4.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>textBox_AtlasPath.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>103, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Ok.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Right</value>
|
||||
</data>
|
||||
<data name="textBox_SkelPath.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>label1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>557, 46</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>label4.Name" xml:space="preserve">
|
||||
<value>label4</value>
|
||||
</data>
|
||||
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>OpenSpineDialog</value>
|
||||
</data>
|
||||
<data name=">>button_SelectAtlas.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Ok.Text" xml:space="preserve">
|
||||
<value>确认</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.Text" xml:space="preserve">
|
||||
<value>...</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>button_SelectSkel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label2.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="label4.Text" xml:space="preserve">
|
||||
<value>说明:如果没有选择atlas,则会自动读取与skel同目录下同名的atlas文件</value>
|
||||
</data>
|
||||
<data name="label4.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 12, 11, 12</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="label4.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>11, 12</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>28, 30</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="label1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Atlas.Title" xml:space="preserve">
|
||||
<value>选择atlas文件</value>
|
||||
</data>
|
||||
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Atlas.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.ZOrder" xml:space="preserve">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Name" xml:space="preserve">
|
||||
<value>comboBox_Version</value>
|
||||
</data>
|
||||
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>63, 118</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>660, 238</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>109, 114</value>
|
||||
</data>
|
||||
<data name=">>label2.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>97, 20</value>
|
||||
</data>
|
||||
<data name="label4.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="label4.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleCenter</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.ZOrder" xml:space="preserve">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="button_Cancel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>109, 80</value>
|
||||
</data>
|
||||
<data name="label2.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Name" xml:space="preserve">
|
||||
<value>button_Cancel</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>28, 30</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="label2.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name=">>label1.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="textBox_SkelPath.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>444, 27</value>
|
||||
</data>
|
||||
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>42, 20</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name=">>button_SelectAtlas.Name" xml:space="preserve">
|
||||
<value>button_SelectAtlas</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>打开骨骼</value>
|
||||
</data>
|
||||
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>8, 51</value>
|
||||
</data>
|
||||
<data name=">>label2.Name" xml:space="preserve">
|
||||
<value>label2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>36, 12</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Skel.Name" xml:space="preserve">
|
||||
<value>openFileDialog_Skel</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Filter" xml:space="preserve">
|
||||
<value>所有文件 (*.*)|*.*|skel 文件 (*.skel; *.json)|*.skel;*.json</value>
|
||||
</data>
|
||||
<data name="label3.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name="label4.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>660, 238</value>
|
||||
</data>
|
||||
<data name=">>panel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name=">>textBox_AtlasPath.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label2.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Language" type="System.Globalization.CultureInfo, System.Private.CoreLib, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>en</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog_Atlas.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>349, 29</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog_Skel.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>58, 25</value>
|
||||
</metadata>
|
||||
</root>
|
||||
181
SpineViewer/Dialogs/ProgressDialog.Designer.cs
generated
181
SpineViewer/Dialogs/ProgressDialog.Designer.cs
generated
@@ -20,114 +20,85 @@
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
progressBar = new ProgressBar();
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
button_Cancel = new Button();
|
||||
label_Tip = new Label();
|
||||
backgroundWorker = new System.ComponentModel.BackgroundWorker();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// progressBar
|
||||
//
|
||||
progressBar.Dock = DockStyle.Fill;
|
||||
progressBar.Location = new Point(3, 57);
|
||||
progressBar.Name = "progressBar";
|
||||
progressBar.Size = new Size(552, 34);
|
||||
progressBar.Style = ProgressBarStyle.Continuous;
|
||||
progressBar.TabIndex = 0;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(0, 0);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(30);
|
||||
panel1.Size = new Size(618, 206);
|
||||
panel1.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.ColumnCount = 1;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.Controls.Add(progressBar, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_Cancel, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label_Tip, 0, 0);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(30, 30);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 3;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(558, 146);
|
||||
tableLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
button_Cancel.Anchor = AnchorStyles.Bottom;
|
||||
button_Cancel.Location = new Point(223, 109);
|
||||
button_Cancel.Margin = new Padding(3, 15, 3, 3);
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.Size = new Size(112, 34);
|
||||
button_Cancel.TabIndex = 9;
|
||||
button_Cancel.Text = "取消";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// label_Tip
|
||||
//
|
||||
label_Tip.AutoSize = true;
|
||||
label_Tip.Dock = DockStyle.Fill;
|
||||
label_Tip.Location = new Point(3, 10);
|
||||
label_Tip.Margin = new Padding(3, 10, 3, 10);
|
||||
label_Tip.Name = "label_Tip";
|
||||
label_Tip.Size = new Size(552, 34);
|
||||
label_Tip.TabIndex = 10;
|
||||
label_Tip.Text = "初始化...";
|
||||
//
|
||||
// backgroundWorker
|
||||
//
|
||||
backgroundWorker.WorkerReportsProgress = true;
|
||||
backgroundWorker.WorkerSupportsCancellation = true;
|
||||
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
|
||||
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
|
||||
//
|
||||
// ProgressDialog
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(618, 206);
|
||||
ControlBox = false;
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ProgressDialog";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "进度";
|
||||
panel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProgressDialog));
|
||||
progressBar = new ProgressBar();
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
button_Cancel = new Button();
|
||||
label_Tip = new Label();
|
||||
backgroundWorker = new System.ComponentModel.BackgroundWorker();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// progressBar
|
||||
//
|
||||
resources.ApplyResources(progressBar, "progressBar");
|
||||
progressBar.Name = "progressBar";
|
||||
progressBar.Style = ProgressBarStyle.Continuous;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(progressBar, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_Cancel, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label_Tip, 0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
resources.ApplyResources(button_Cancel, "button_Cancel");
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// label_Tip
|
||||
//
|
||||
resources.ApplyResources(label_Tip, "label_Tip");
|
||||
label_Tip.Name = "label_Tip";
|
||||
//
|
||||
// backgroundWorker
|
||||
//
|
||||
backgroundWorker.WorkerReportsProgress = true;
|
||||
backgroundWorker.WorkerSupportsCancellation = true;
|
||||
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
|
||||
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
|
||||
//
|
||||
// ProgressDialog
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ControlBox = false;
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ProgressDialog";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
panel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private ProgressBar progressBar;
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private System.ComponentModel.BackgroundWorker backgroundWorker;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using NLog;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
@@ -12,6 +14,13 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ProgressDialog : Form
|
||||
{
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public ProgressDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BackgroundWorker.DoWork 接口暴露
|
||||
/// </summary>
|
||||
@@ -32,11 +41,6 @@ namespace SpineViewer.Dialogs
|
||||
/// </summary>
|
||||
public void RunWorkerAsync(object? argument) => backgroundWorker.RunWorkerAsync(argument);
|
||||
|
||||
public ProgressDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
|
||||
{
|
||||
label_Tip.Text = e.UserState as string;
|
||||
@@ -47,8 +51,8 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
Program.Logger.Error(e.Error.ToString());
|
||||
MessageBox.Error(e.Error.ToString(), "执行出错");
|
||||
logger.Error(e.Error.ToString());
|
||||
MessagePopup.Error(e.Error.ToString(), Properties.Resources.runtimeError);
|
||||
DialogResult = DialogResult.Abort;
|
||||
}
|
||||
else if (e.Cancelled)
|
||||
|
||||
129
SpineViewer/Dialogs/ProgressDialog.en.resx
Normal file
129
SpineViewer/Dialogs/ProgressDialog.en.resx
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="label_Tip.Text" xml:space="preserve">
|
||||
<value>Initializing...</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Progress</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,6 +117,199 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name=">>button_Cancel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name=">>panel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Cancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name=">>progressBar.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name=">>panel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_Cancel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>22, 25</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="label_Tip.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 8, 2, 8</value>
|
||||
</data>
|
||||
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Name" xml:space="preserve">
|
||||
<value>label_Tip</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Name" xml:space="preserve">
|
||||
<value>button_Cancel</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="progressBar.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 50</value>
|
||||
</data>
|
||||
<data name="label_Tip.Text" xml:space="preserve">
|
||||
<value>初始化...</value>
|
||||
</data>
|
||||
<data name="label_Tip.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name=">>backgroundWorker.Type" xml:space="preserve">
|
||||
<value>System.ComponentModel.BackgroundWorker, System.ComponentModel.EventBasedAsync, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="progressBar" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="button_Cancel" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label_Tip" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 12, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>progressBar.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ProgressBar, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name="label_Tip.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="progressBar.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>401, 28</value>
|
||||
</data>
|
||||
<data name="label_Tip.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>progressBar.Name" xml:space="preserve">
|
||||
<value>progressBar</value>
|
||||
</data>
|
||||
<data name=">>panel1.Name" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>449, 172</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>ProgressDialog</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="progressBar.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="label_Tip.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 8</value>
|
||||
</data>
|
||||
<data name=">>backgroundWorker.Name" xml:space="preserve">
|
||||
<value>backgroundWorker</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>449, 172</value>
|
||||
</data>
|
||||
<data name="label_Tip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>401, 32</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>162, 92</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>进度</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>22, 25, 22, 25</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>405, 122</value>
|
||||
</data>
|
||||
<data name="progressBar.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>panel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>progressBar.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="progressBar.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Language" type="System.Globalization.CultureInfo, System.Private.CoreLib, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>en</value>
|
||||
</metadata>
|
||||
<metadata name="backgroundWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
|
||||
21
SpineViewer/Extensions/NLogExtension.cs
Normal file
21
SpineViewer/Extensions/NLogExtension.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpineViewer.Extensions
|
||||
{
|
||||
public static class NLogExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 输出当前进程的内存占用
|
||||
/// </summary>
|
||||
public static void LogCurrentProcessMemoryUsage(this NLog.Logger logger)
|
||||
{
|
||||
var process = Process.GetCurrentProcess();
|
||||
logger.Info("Current memory usage for {}: {:F2} MB", process.ProcessName, process.WorkingSet64 / 1024.0 / 1024.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
118
SpineViewer/Extensions/SFMLExtension.cs
Normal file
118
SpineViewer/Extensions/SFMLExtension.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpineViewer.Extensions
|
||||
{
|
||||
public static class SFMLExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取并集范围
|
||||
/// </summary>
|
||||
public static RectangleF Union(this RectangleF bounds, RectangleF other)
|
||||
{
|
||||
var x = Math.Min(bounds.X, other.X);
|
||||
var y = Math.Min(bounds.Y, other.Y);
|
||||
var w = Math.Max(bounds.Right, other.Right) - x;
|
||||
var h = Math.Max(bounds.Bottom, other.Bottom) - y;
|
||||
return new(x, y, w, h);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
|
||||
/// </summary>
|
||||
public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution) => GetCanvasBounds(bounds, resolution, new(0), new(0));
|
||||
|
||||
/// <summary>
|
||||
/// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
|
||||
/// </summary>
|
||||
public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution, Padding margin) => GetCanvasBounds(bounds, resolution, margin, new(0));
|
||||
|
||||
/// <summary>
|
||||
/// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
|
||||
/// </summary>
|
||||
public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution, Padding margin, Padding padding)
|
||||
{
|
||||
float sizeW = bounds.Width;
|
||||
float sizeH = bounds.Height;
|
||||
float innerW = resolution.Width - padding.Horizontal;
|
||||
float innerH = resolution.Height - padding.Vertical;
|
||||
float scale = Math.Max(Math.Abs(sizeW / innerW), Math.Abs(sizeH / innerH)); // 取两方向上较大的缩放比, 以此让画布可以覆盖内容
|
||||
float scaleW = scale * Math.Sign(sizeW);
|
||||
float scaleH = scale * Math.Sign(sizeH);
|
||||
|
||||
innerW *= scaleW;
|
||||
innerH *= scaleH;
|
||||
|
||||
var x = bounds.X - (innerW - sizeW) / 2 - (margin.Left + padding.Left) * scaleW;
|
||||
var y = bounds.Y - (innerH - sizeH) / 2 - (margin.Top + padding.Top) * scaleH;
|
||||
var w = (resolution.Width + margin.Horizontal) * scaleW;
|
||||
var h = (resolution.Height + margin.Vertical) * scaleH;
|
||||
return new(x, y, w, h);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象
|
||||
/// </summary>
|
||||
public static Bitmap CopyToBitmap(this SFML.Graphics.Image image)
|
||||
{
|
||||
image.SaveToMemory(out var imgBuffer, "bmp");
|
||||
using var stream = new MemoryStream(imgBuffer);
|
||||
using var bitmap = new Bitmap(stream);
|
||||
return new(bitmap); // 必须重复构造一个副本才能摆脱对流的依赖, 否则之后使用会报错
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象
|
||||
/// </summary>
|
||||
public static Bitmap CopyToBitmap(this SFML.Graphics.Texture texture)
|
||||
{
|
||||
using var image = texture.CopyToImage();
|
||||
return image.CopyToBitmap();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取视区的包围盒
|
||||
/// </summary>
|
||||
public static RectangleF GetBounds(this SFML.Graphics.View view)
|
||||
{
|
||||
return new(
|
||||
view.Center.X - view.Size.X / 2,
|
||||
view.Center.Y - view.Size.Y / 2,
|
||||
view.Size.X,
|
||||
view.Size.Y
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按画布设置视区, 边缘和填充区域将不会出现内容
|
||||
/// </summary>
|
||||
public static void SetViewport(this SFML.Graphics.View view, Size resolution, Padding margin) => SetViewport(view, resolution, margin, new(0));
|
||||
|
||||
/// <summary>
|
||||
/// 按画布设置视区, 边缘和填充区域将不会出现内容
|
||||
/// </summary>
|
||||
public static void SetViewport(this SFML.Graphics.View view, Size resolution, Padding margin, Padding padding)
|
||||
{
|
||||
var innerW = resolution.Width - padding.Horizontal;
|
||||
var innerH = resolution.Height - padding.Vertical;
|
||||
|
||||
float width = resolution.Width + margin.Horizontal;
|
||||
float height = resolution.Height + margin.Vertical;
|
||||
|
||||
view.Viewport = new(
|
||||
(margin.Left + padding.Left) / width,
|
||||
(margin.Top + padding.Top) / height,
|
||||
innerW / width,
|
||||
innerH / height
|
||||
);
|
||||
|
||||
var bounds = view.GetBounds().GetCanvasBounds(new(innerW, innerH));
|
||||
|
||||
view.Center = new(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2);
|
||||
view.Size = new(bounds.Width, bounds.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
51
SpineViewer/Forms/SpinePreviewFullScreenForm.Designer.cs
generated
Normal file
51
SpineViewer/Forms/SpinePreviewFullScreenForm.Designer.cs
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace SpineViewer.Forms
|
||||
{
|
||||
partial class SpinePreviewFullScreenForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
SuspendLayout();
|
||||
//
|
||||
// SpinePreviewFullScreenForm
|
||||
//
|
||||
AutoScaleMode = AutoScaleMode.None;
|
||||
ClientSize = new Size(512, 512);
|
||||
ControlBox = false;
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "SpinePreviewFullScreenForm";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
TopMost = true;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
35
SpineViewer/Forms/SpinePreviewFullScreenForm.cs
Normal file
35
SpineViewer/Forms/SpinePreviewFullScreenForm.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using SpineViewer.Natives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Forms
|
||||
{
|
||||
[ToolboxItem(true)]
|
||||
[Designer(typeof(ComponentDesigner), typeof(IDesigner))]
|
||||
[DesignTimeVisible(true)]
|
||||
public partial class SpinePreviewFullScreenForm: Form
|
||||
{
|
||||
public SpinePreviewFullScreenForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
var cp = base.CreateParams;
|
||||
cp.ExStyle |= Win32.WS_EX_TOOLWINDOW;
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace SpineViewer
|
||||
{
|
||||
partial class MainForm
|
||||
partial class SpineViewerForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -29,18 +29,45 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpineViewerForm));
|
||||
splitContainer_MainForm = new SplitContainer();
|
||||
splitContainer_Functional = new SplitContainer();
|
||||
splitContainer_Information = new SplitContainer();
|
||||
groupBox_SkelList = new GroupBox();
|
||||
spineListView = new SpineViewer.Controls.SpineListView();
|
||||
spineViewPropertyGrid = new SpineViewer.Controls.SpineViewPropertyGrid();
|
||||
splitContainer_Config = new SplitContainer();
|
||||
groupBox_PreviewConfig = new GroupBox();
|
||||
propertyGrid_Previewer = new PropertyGrid();
|
||||
groupBox_SkelConfig = new GroupBox();
|
||||
groupBox_Preview = new GroupBox();
|
||||
spinePreviewPanel = new SpineViewer.Controls.SpinePreviewPanel();
|
||||
rtbLog = new RichTextBox();
|
||||
menuStrip = new MenuStrip();
|
||||
toolStripMenuItem_File = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Open = new ToolStripMenuItem();
|
||||
toolStripMenuItem_BatchOpen = new ToolStripMenuItem();
|
||||
toolStripSeparator1 = new ToolStripSeparator();
|
||||
toolStripMenuItem_Export = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportPreview = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportFrame = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportFrameSequence = new ToolStripMenuItem();
|
||||
toolStripSeparator4 = new ToolStripSeparator();
|
||||
toolStripMenuItem_ExportGif = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportWebp = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportAvif = new ToolStripMenuItem();
|
||||
toolStripSeparator5 = new ToolStripSeparator();
|
||||
toolStripMenuItem_ExportMp4 = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportWebm = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportMkv = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportMov = new ToolStripMenuItem();
|
||||
toolStripSeparator6 = new ToolStripSeparator();
|
||||
toolStripMenuItem_ExportCustom = new ToolStripMenuItem();
|
||||
toolStripSeparator2 = new ToolStripSeparator();
|
||||
toolStripMenuItem_Exit = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Function = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ResetAnimation = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Texture = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ForceSmooth = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ForceRepeated = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ForceMipmap = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Tool = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ConvertFileFormat = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Download = new ToolStripMenuItem();
|
||||
@@ -49,22 +76,14 @@
|
||||
toolStripMenuItem_Diagnostics = new ToolStripMenuItem();
|
||||
toolStripSeparator3 = new ToolStripSeparator();
|
||||
toolStripMenuItem_About = new ToolStripMenuItem();
|
||||
rtbLog = new RichTextBox();
|
||||
splitContainer_MainForm = new SplitContainer();
|
||||
splitContainer_Functional = new SplitContainer();
|
||||
splitContainer_Information = new SplitContainer();
|
||||
groupBox_SkelList = new GroupBox();
|
||||
spineListView = new SpineViewer.Controls.SpineListView();
|
||||
propertyGrid_Spine = new PropertyGrid();
|
||||
splitContainer_Config = new SplitContainer();
|
||||
groupBox_SkelConfig = new GroupBox();
|
||||
groupBox_PreviewConfig = new GroupBox();
|
||||
propertyGrid_Previewer = new PropertyGrid();
|
||||
groupBox_Preview = new GroupBox();
|
||||
spinePreviewer = new SpineViewer.Controls.SpinePreviewer();
|
||||
toolStripMenuItem_Debug = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Experiment = new ToolStripMenuItem();
|
||||
toolStripMenuItem_DesktopProjection = new ToolStripMenuItem();
|
||||
ToolStripMenuItem_Language = new ToolStripMenuItem();
|
||||
ToolStripMenuItem_English = new ToolStripMenuItem();
|
||||
ToolStripMenuItem_Chinese = new ToolStripMenuItem();
|
||||
panel_MainForm = new Panel();
|
||||
toolTip = new ToolTip(components);
|
||||
menuStrip.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_MainForm).BeginInit();
|
||||
splitContainer_MainForm.Panel1.SuspendLayout();
|
||||
splitContainer_MainForm.Panel2.SuspendLayout();
|
||||
@@ -82,168 +101,19 @@
|
||||
splitContainer_Config.Panel1.SuspendLayout();
|
||||
splitContainer_Config.Panel2.SuspendLayout();
|
||||
splitContainer_Config.SuspendLayout();
|
||||
groupBox_SkelConfig.SuspendLayout();
|
||||
groupBox_PreviewConfig.SuspendLayout();
|
||||
groupBox_SkelConfig.SuspendLayout();
|
||||
groupBox_Preview.SuspendLayout();
|
||||
menuStrip.SuspendLayout();
|
||||
panel_MainForm.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// menuStrip
|
||||
//
|
||||
menuStrip.BackColor = SystemColors.Control;
|
||||
menuStrip.ImageScalingSize = new Size(24, 24);
|
||||
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Function, toolStripMenuItem_Tool, toolStripMenuItem_Download, toolStripMenuItem_Help });
|
||||
menuStrip.Location = new Point(0, 0);
|
||||
menuStrip.Name = "menuStrip";
|
||||
menuStrip.Size = new Size(1748, 32);
|
||||
menuStrip.TabIndex = 0;
|
||||
menuStrip.Text = "菜单";
|
||||
//
|
||||
// toolStripMenuItem_File
|
||||
//
|
||||
toolStripMenuItem_File.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_Open, toolStripMenuItem_BatchOpen, toolStripSeparator1, toolStripMenuItem_Export, toolStripMenuItem_ExportPreview, toolStripSeparator2, toolStripMenuItem_Exit });
|
||||
toolStripMenuItem_File.Name = "toolStripMenuItem_File";
|
||||
toolStripMenuItem_File.Size = new Size(84, 28);
|
||||
toolStripMenuItem_File.Text = "文件(&F)";
|
||||
//
|
||||
// toolStripMenuItem_Open
|
||||
//
|
||||
toolStripMenuItem_Open.Name = "toolStripMenuItem_Open";
|
||||
toolStripMenuItem_Open.ShortcutKeys = Keys.Control | Keys.O;
|
||||
toolStripMenuItem_Open.Size = new Size(254, 34);
|
||||
toolStripMenuItem_Open.Text = "打开(&O)...";
|
||||
toolStripMenuItem_Open.Click += toolStripMenuItem_Open_Click;
|
||||
//
|
||||
// toolStripMenuItem_BatchOpen
|
||||
//
|
||||
toolStripMenuItem_BatchOpen.Name = "toolStripMenuItem_BatchOpen";
|
||||
toolStripMenuItem_BatchOpen.Size = new Size(254, 34);
|
||||
toolStripMenuItem_BatchOpen.Text = "批量打开(&B)...";
|
||||
toolStripMenuItem_BatchOpen.Click += toolStripMenuItem_BatchOpen_Click;
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
toolStripSeparator1.Size = new Size(251, 6);
|
||||
//
|
||||
// toolStripMenuItem_Export
|
||||
//
|
||||
toolStripMenuItem_Export.Name = "toolStripMenuItem_Export";
|
||||
toolStripMenuItem_Export.ShortcutKeys = Keys.Control | Keys.S;
|
||||
toolStripMenuItem_Export.Size = new Size(254, 34);
|
||||
toolStripMenuItem_Export.Text = "导出(&E)...";
|
||||
toolStripMenuItem_Export.Click += toolStripMenuItem_Export_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportPreview
|
||||
//
|
||||
toolStripMenuItem_ExportPreview.Name = "toolStripMenuItem_ExportPreview";
|
||||
toolStripMenuItem_ExportPreview.Size = new Size(254, 34);
|
||||
toolStripMenuItem_ExportPreview.Text = "导出预览图(&P)...";
|
||||
toolStripMenuItem_ExportPreview.Click += toolStripMenuItem_ExportPreview_Click;
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
toolStripSeparator2.Size = new Size(251, 6);
|
||||
//
|
||||
// toolStripMenuItem_Exit
|
||||
//
|
||||
toolStripMenuItem_Exit.Name = "toolStripMenuItem_Exit";
|
||||
toolStripMenuItem_Exit.ShortcutKeys = Keys.Alt | Keys.F4;
|
||||
toolStripMenuItem_Exit.Size = new Size(254, 34);
|
||||
toolStripMenuItem_Exit.Text = "退出(&X)";
|
||||
toolStripMenuItem_Exit.Click += toolStripMenuItem_Exit_Click;
|
||||
//
|
||||
// toolStripMenuItem_Function
|
||||
//
|
||||
toolStripMenuItem_Function.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ResetAnimation });
|
||||
toolStripMenuItem_Function.Name = "toolStripMenuItem_Function";
|
||||
toolStripMenuItem_Function.Size = new Size(87, 28);
|
||||
toolStripMenuItem_Function.Text = "功能(&G)";
|
||||
//
|
||||
// toolStripMenuItem_ResetAnimation
|
||||
//
|
||||
toolStripMenuItem_ResetAnimation.Name = "toolStripMenuItem_ResetAnimation";
|
||||
toolStripMenuItem_ResetAnimation.Size = new Size(242, 34);
|
||||
toolStripMenuItem_ResetAnimation.Text = "重置动画时间(&R)";
|
||||
toolStripMenuItem_ResetAnimation.Click += toolStripMenuItem_ResetAnimation_Click;
|
||||
//
|
||||
// toolStripMenuItem_Tool
|
||||
//
|
||||
toolStripMenuItem_Tool.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ConvertFileFormat });
|
||||
toolStripMenuItem_Tool.Name = "toolStripMenuItem_Tool";
|
||||
toolStripMenuItem_Tool.Size = new Size(84, 28);
|
||||
toolStripMenuItem_Tool.Text = "工具(&T)";
|
||||
//
|
||||
// toolStripMenuItem_ConvertFileFormat
|
||||
//
|
||||
toolStripMenuItem_ConvertFileFormat.Name = "toolStripMenuItem_ConvertFileFormat";
|
||||
toolStripMenuItem_ConvertFileFormat.Size = new Size(254, 34);
|
||||
toolStripMenuItem_ConvertFileFormat.Text = "转换文件格式(&C)...";
|
||||
toolStripMenuItem_ConvertFileFormat.Click += toolStripMenuItem_ConvertFileFormat_Click;
|
||||
//
|
||||
// toolStripMenuItem_Download
|
||||
//
|
||||
toolStripMenuItem_Download.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ManageResource });
|
||||
toolStripMenuItem_Download.Name = "toolStripMenuItem_Download";
|
||||
toolStripMenuItem_Download.Size = new Size(88, 28);
|
||||
toolStripMenuItem_Download.Text = "下载(&D)";
|
||||
//
|
||||
// toolStripMenuItem_ManageResource
|
||||
//
|
||||
toolStripMenuItem_ManageResource.Name = "toolStripMenuItem_ManageResource";
|
||||
toolStripMenuItem_ManageResource.Size = new Size(260, 34);
|
||||
toolStripMenuItem_ManageResource.Text = "管理下载资源(&M)...";
|
||||
toolStripMenuItem_ManageResource.Click += toolStripMenuItem_ManageResource_Click;
|
||||
//
|
||||
// toolStripMenuItem_Help
|
||||
//
|
||||
toolStripMenuItem_Help.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_Diagnostics, toolStripSeparator3, toolStripMenuItem_About });
|
||||
toolStripMenuItem_Help.Name = "toolStripMenuItem_Help";
|
||||
toolStripMenuItem_Help.Size = new Size(88, 28);
|
||||
toolStripMenuItem_Help.Text = "帮助(&H)";
|
||||
//
|
||||
// toolStripMenuItem_Diagnostics
|
||||
//
|
||||
toolStripMenuItem_Diagnostics.Name = "toolStripMenuItem_Diagnostics";
|
||||
toolStripMenuItem_Diagnostics.Size = new Size(208, 34);
|
||||
toolStripMenuItem_Diagnostics.Text = "诊断信息(&D)";
|
||||
toolStripMenuItem_Diagnostics.Click += toolStripMenuItem_Diagnostics_Click;
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
toolStripSeparator3.Size = new Size(205, 6);
|
||||
//
|
||||
// toolStripMenuItem_About
|
||||
//
|
||||
toolStripMenuItem_About.Name = "toolStripMenuItem_About";
|
||||
toolStripMenuItem_About.Size = new Size(208, 34);
|
||||
toolStripMenuItem_About.Text = "关于(&A)";
|
||||
toolStripMenuItem_About.Click += toolStripMenuItem_About_Click;
|
||||
//
|
||||
// rtbLog
|
||||
//
|
||||
rtbLog.BackColor = SystemColors.Window;
|
||||
rtbLog.BorderStyle = BorderStyle.None;
|
||||
rtbLog.Dock = DockStyle.Fill;
|
||||
rtbLog.Font = new Font("Consolas", 9F);
|
||||
rtbLog.Location = new Point(0, 0);
|
||||
rtbLog.Margin = new Padding(3, 2, 3, 2);
|
||||
rtbLog.Name = "rtbLog";
|
||||
rtbLog.ReadOnly = true;
|
||||
rtbLog.Size = new Size(1728, 114);
|
||||
rtbLog.TabIndex = 0;
|
||||
rtbLog.Text = "";
|
||||
rtbLog.WordWrap = false;
|
||||
//
|
||||
// splitContainer_MainForm
|
||||
//
|
||||
splitContainer_MainForm.Cursor = Cursors.SizeNS;
|
||||
splitContainer_MainForm.Dock = DockStyle.Fill;
|
||||
splitContainer_MainForm.Location = new Point(10, 5);
|
||||
resources.ApplyResources(splitContainer_MainForm, "splitContainer_MainForm");
|
||||
splitContainer_MainForm.FixedPanel = FixedPanel.Panel2;
|
||||
splitContainer_MainForm.Name = "splitContainer_MainForm";
|
||||
splitContainer_MainForm.Orientation = Orientation.Horizontal;
|
||||
//
|
||||
// splitContainer_MainForm.Panel1
|
||||
//
|
||||
@@ -254,9 +124,6 @@
|
||||
//
|
||||
splitContainer_MainForm.Panel2.Controls.Add(rtbLog);
|
||||
splitContainer_MainForm.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_MainForm.Size = new Size(1728, 997);
|
||||
splitContainer_MainForm.SplitterDistance = 879;
|
||||
splitContainer_MainForm.TabIndex = 3;
|
||||
splitContainer_MainForm.TabStop = false;
|
||||
splitContainer_MainForm.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_MainForm.MouseUp += splitContainer_MouseUp;
|
||||
@@ -264,8 +131,8 @@
|
||||
// splitContainer_Functional
|
||||
//
|
||||
splitContainer_Functional.Cursor = Cursors.SizeWE;
|
||||
splitContainer_Functional.Dock = DockStyle.Fill;
|
||||
splitContainer_Functional.Location = new Point(0, 0);
|
||||
resources.ApplyResources(splitContainer_Functional, "splitContainer_Functional");
|
||||
splitContainer_Functional.FixedPanel = FixedPanel.Panel1;
|
||||
splitContainer_Functional.Name = "splitContainer_Functional";
|
||||
//
|
||||
// splitContainer_Functional.Panel1
|
||||
@@ -277,9 +144,6 @@
|
||||
//
|
||||
splitContainer_Functional.Panel2.Controls.Add(groupBox_Preview);
|
||||
splitContainer_Functional.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_Functional.Size = new Size(1728, 879);
|
||||
splitContainer_Functional.SplitterDistance = 747;
|
||||
splitContainer_Functional.TabIndex = 2;
|
||||
splitContainer_Functional.TabStop = false;
|
||||
splitContainer_Functional.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_Functional.MouseUp += splitContainer_MouseUp;
|
||||
@@ -287,8 +151,7 @@
|
||||
// splitContainer_Information
|
||||
//
|
||||
splitContainer_Information.Cursor = Cursors.SizeWE;
|
||||
splitContainer_Information.Dock = DockStyle.Fill;
|
||||
splitContainer_Information.Location = new Point(0, 0);
|
||||
resources.ApplyResources(splitContainer_Information, "splitContainer_Information");
|
||||
splitContainer_Information.Name = "splitContainer_Information";
|
||||
//
|
||||
// splitContainer_Information.Panel1
|
||||
@@ -300,9 +163,6 @@
|
||||
//
|
||||
splitContainer_Information.Panel2.Controls.Add(splitContainer_Config);
|
||||
splitContainer_Information.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_Information.Size = new Size(747, 879);
|
||||
splitContainer_Information.SplitterDistance = 399;
|
||||
splitContainer_Information.TabIndex = 1;
|
||||
splitContainer_Information.TabStop = false;
|
||||
splitContainer_Information.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_Information.MouseUp += splitContainer_MouseUp;
|
||||
@@ -310,145 +170,326 @@
|
||||
// groupBox_SkelList
|
||||
//
|
||||
groupBox_SkelList.Controls.Add(spineListView);
|
||||
groupBox_SkelList.Dock = DockStyle.Fill;
|
||||
groupBox_SkelList.Location = new Point(0, 0);
|
||||
resources.ApplyResources(groupBox_SkelList, "groupBox_SkelList");
|
||||
groupBox_SkelList.Name = "groupBox_SkelList";
|
||||
groupBox_SkelList.Size = new Size(399, 879);
|
||||
groupBox_SkelList.TabIndex = 0;
|
||||
groupBox_SkelList.TabStop = false;
|
||||
groupBox_SkelList.Text = "模型列表";
|
||||
//
|
||||
// spineListView
|
||||
//
|
||||
spineListView.Dock = DockStyle.Fill;
|
||||
spineListView.Location = new Point(3, 26);
|
||||
resources.ApplyResources(spineListView, "spineListView");
|
||||
spineListView.Name = "spineListView";
|
||||
spineListView.PropertyGrid = propertyGrid_Spine;
|
||||
spineListView.Size = new Size(393, 850);
|
||||
spineListView.TabIndex = 0;
|
||||
spineListView.SpinePropertyGrid = spineViewPropertyGrid;
|
||||
//
|
||||
// propertyGrid_Spine
|
||||
// spineViewPropertyGrid
|
||||
//
|
||||
propertyGrid_Spine.Dock = DockStyle.Fill;
|
||||
propertyGrid_Spine.HelpVisible = false;
|
||||
propertyGrid_Spine.Location = new Point(3, 26);
|
||||
propertyGrid_Spine.Name = "propertyGrid_Spine";
|
||||
propertyGrid_Spine.Size = new Size(338, 485);
|
||||
propertyGrid_Spine.TabIndex = 0;
|
||||
propertyGrid_Spine.ToolbarVisible = false;
|
||||
propertyGrid_Spine.PropertyValueChanged += propertyGrid_PropertyValueChanged;
|
||||
resources.ApplyResources(spineViewPropertyGrid, "spineViewPropertyGrid");
|
||||
spineViewPropertyGrid.Name = "spineViewPropertyGrid";
|
||||
//
|
||||
// splitContainer_Config
|
||||
//
|
||||
splitContainer_Config.Cursor = Cursors.SizeNS;
|
||||
splitContainer_Config.Dock = DockStyle.Fill;
|
||||
splitContainer_Config.Location = new Point(0, 0);
|
||||
resources.ApplyResources(splitContainer_Config, "splitContainer_Config");
|
||||
splitContainer_Config.Name = "splitContainer_Config";
|
||||
splitContainer_Config.Orientation = Orientation.Horizontal;
|
||||
//
|
||||
// splitContainer_Config.Panel1
|
||||
//
|
||||
splitContainer_Config.Panel1.Controls.Add(groupBox_SkelConfig);
|
||||
splitContainer_Config.Panel1.Cursor = Cursors.Default;
|
||||
splitContainer_Config.Panel1.Controls.Add(groupBox_PreviewConfig);
|
||||
//
|
||||
// splitContainer_Config.Panel2
|
||||
//
|
||||
splitContainer_Config.Panel2.Controls.Add(groupBox_PreviewConfig);
|
||||
splitContainer_Config.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_Config.Size = new Size(344, 879);
|
||||
splitContainer_Config.SplitterDistance = 514;
|
||||
splitContainer_Config.TabIndex = 0;
|
||||
splitContainer_Config.TabStop = false;
|
||||
splitContainer_Config.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_Config.MouseUp += splitContainer_MouseUp;
|
||||
//
|
||||
// groupBox_SkelConfig
|
||||
//
|
||||
groupBox_SkelConfig.Controls.Add(propertyGrid_Spine);
|
||||
groupBox_SkelConfig.Dock = DockStyle.Fill;
|
||||
groupBox_SkelConfig.Location = new Point(0, 0);
|
||||
groupBox_SkelConfig.Name = "groupBox_SkelConfig";
|
||||
groupBox_SkelConfig.Size = new Size(344, 514);
|
||||
groupBox_SkelConfig.TabIndex = 0;
|
||||
groupBox_SkelConfig.TabStop = false;
|
||||
groupBox_SkelConfig.Text = "模型参数";
|
||||
splitContainer_Config.Panel2.Controls.Add(groupBox_SkelConfig);
|
||||
//
|
||||
// groupBox_PreviewConfig
|
||||
//
|
||||
groupBox_PreviewConfig.Controls.Add(propertyGrid_Previewer);
|
||||
groupBox_PreviewConfig.Dock = DockStyle.Fill;
|
||||
groupBox_PreviewConfig.Location = new Point(0, 0);
|
||||
resources.ApplyResources(groupBox_PreviewConfig, "groupBox_PreviewConfig");
|
||||
groupBox_PreviewConfig.Name = "groupBox_PreviewConfig";
|
||||
groupBox_PreviewConfig.Size = new Size(344, 361);
|
||||
groupBox_PreviewConfig.TabIndex = 1;
|
||||
groupBox_PreviewConfig.TabStop = false;
|
||||
groupBox_PreviewConfig.Text = "画面参数";
|
||||
//
|
||||
// propertyGrid_Previewer
|
||||
//
|
||||
propertyGrid_Previewer.Dock = DockStyle.Fill;
|
||||
propertyGrid_Previewer.HelpVisible = false;
|
||||
propertyGrid_Previewer.Location = new Point(3, 26);
|
||||
resources.ApplyResources(propertyGrid_Previewer, "propertyGrid_Previewer");
|
||||
propertyGrid_Previewer.Name = "propertyGrid_Previewer";
|
||||
propertyGrid_Previewer.Size = new Size(338, 332);
|
||||
propertyGrid_Previewer.TabIndex = 1;
|
||||
propertyGrid_Previewer.ToolbarVisible = false;
|
||||
propertyGrid_Previewer.PropertyValueChanged += propertyGrid_PropertyValueChanged;
|
||||
//
|
||||
// groupBox_SkelConfig
|
||||
//
|
||||
groupBox_SkelConfig.Controls.Add(spineViewPropertyGrid);
|
||||
resources.ApplyResources(groupBox_SkelConfig, "groupBox_SkelConfig");
|
||||
groupBox_SkelConfig.Name = "groupBox_SkelConfig";
|
||||
groupBox_SkelConfig.TabStop = false;
|
||||
//
|
||||
// groupBox_Preview
|
||||
//
|
||||
groupBox_Preview.Controls.Add(spinePreviewer);
|
||||
groupBox_Preview.Dock = DockStyle.Fill;
|
||||
groupBox_Preview.Location = new Point(0, 0);
|
||||
groupBox_Preview.Controls.Add(spinePreviewPanel);
|
||||
resources.ApplyResources(groupBox_Preview, "groupBox_Preview");
|
||||
groupBox_Preview.Name = "groupBox_Preview";
|
||||
groupBox_Preview.Size = new Size(977, 879);
|
||||
groupBox_Preview.TabIndex = 1;
|
||||
groupBox_Preview.TabStop = false;
|
||||
groupBox_Preview.Text = "预览画面";
|
||||
//
|
||||
// spinePreviewer
|
||||
// spinePreviewPanel
|
||||
//
|
||||
spinePreviewer.BackColor = SystemColors.ControlDark;
|
||||
spinePreviewer.Dock = DockStyle.Fill;
|
||||
spinePreviewer.Location = new Point(3, 26);
|
||||
spinePreviewer.Name = "spinePreviewer";
|
||||
spinePreviewer.PropertyGrid = propertyGrid_Previewer;
|
||||
spinePreviewer.Size = new Size(971, 850);
|
||||
spinePreviewer.SpineListView = spineListView;
|
||||
spinePreviewer.TabIndex = 0;
|
||||
spinePreviewer.MouseUp += spinePreviewer_MouseUp;
|
||||
resources.ApplyResources(spinePreviewPanel, "spinePreviewPanel");
|
||||
spinePreviewPanel.Name = "spinePreviewPanel";
|
||||
spinePreviewPanel.PropertyGrid = propertyGrid_Previewer;
|
||||
spinePreviewPanel.SpineListView = spineListView;
|
||||
//
|
||||
// rtbLog
|
||||
//
|
||||
rtbLog.BackColor = SystemColors.Window;
|
||||
rtbLog.BorderStyle = BorderStyle.None;
|
||||
resources.ApplyResources(rtbLog, "rtbLog");
|
||||
rtbLog.Name = "rtbLog";
|
||||
rtbLog.ReadOnly = true;
|
||||
//
|
||||
// menuStrip
|
||||
//
|
||||
menuStrip.BackColor = SystemColors.Control;
|
||||
menuStrip.ImageScalingSize = new Size(24, 24);
|
||||
menuStrip.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_File, toolStripMenuItem_Texture, toolStripMenuItem_Tool, toolStripMenuItem_Download, toolStripMenuItem_Help, toolStripMenuItem_Experiment, ToolStripMenuItem_Language });
|
||||
resources.ApplyResources(menuStrip, "menuStrip");
|
||||
menuStrip.Name = "menuStrip";
|
||||
//
|
||||
// toolStripMenuItem_File
|
||||
//
|
||||
toolStripMenuItem_File.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_Open, toolStripMenuItem_BatchOpen, toolStripSeparator1, toolStripMenuItem_Export, toolStripSeparator2, toolStripMenuItem_Exit });
|
||||
toolStripMenuItem_File.Name = "toolStripMenuItem_File";
|
||||
resources.ApplyResources(toolStripMenuItem_File, "toolStripMenuItem_File");
|
||||
//
|
||||
// toolStripMenuItem_Open
|
||||
//
|
||||
toolStripMenuItem_Open.Name = "toolStripMenuItem_Open";
|
||||
resources.ApplyResources(toolStripMenuItem_Open, "toolStripMenuItem_Open");
|
||||
toolStripMenuItem_Open.Click += toolStripMenuItem_Open_Click;
|
||||
//
|
||||
// toolStripMenuItem_BatchOpen
|
||||
//
|
||||
toolStripMenuItem_BatchOpen.Name = "toolStripMenuItem_BatchOpen";
|
||||
resources.ApplyResources(toolStripMenuItem_BatchOpen, "toolStripMenuItem_BatchOpen");
|
||||
toolStripMenuItem_BatchOpen.Click += toolStripMenuItem_BatchOpen_Click;
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1");
|
||||
//
|
||||
// toolStripMenuItem_Export
|
||||
//
|
||||
toolStripMenuItem_Export.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ExportFrame, toolStripMenuItem_ExportFrameSequence, toolStripSeparator4, toolStripMenuItem_ExportGif, toolStripMenuItem_ExportWebp, toolStripMenuItem_ExportAvif, toolStripSeparator5, toolStripMenuItem_ExportMp4, toolStripMenuItem_ExportWebm, toolStripMenuItem_ExportMkv, toolStripMenuItem_ExportMov, toolStripSeparator6, toolStripMenuItem_ExportCustom });
|
||||
toolStripMenuItem_Export.Name = "toolStripMenuItem_Export";
|
||||
resources.ApplyResources(toolStripMenuItem_Export, "toolStripMenuItem_Export");
|
||||
//
|
||||
// toolStripMenuItem_ExportFrame
|
||||
//
|
||||
toolStripMenuItem_ExportFrame.Name = "toolStripMenuItem_ExportFrame";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportFrame, "toolStripMenuItem_ExportFrame");
|
||||
toolStripMenuItem_ExportFrame.Click += toolStripMenuItem_ExportFrame_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportFrameSequence
|
||||
//
|
||||
toolStripMenuItem_ExportFrameSequence.Name = "toolStripMenuItem_ExportFrameSequence";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportFrameSequence, "toolStripMenuItem_ExportFrameSequence");
|
||||
toolStripMenuItem_ExportFrameSequence.Click += toolStripMenuItem_ExportFrameSequence_Click;
|
||||
//
|
||||
// toolStripSeparator4
|
||||
//
|
||||
toolStripSeparator4.Name = "toolStripSeparator4";
|
||||
resources.ApplyResources(toolStripSeparator4, "toolStripSeparator4");
|
||||
//
|
||||
// toolStripMenuItem_ExportGif
|
||||
//
|
||||
toolStripMenuItem_ExportGif.Name = "toolStripMenuItem_ExportGif";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportGif, "toolStripMenuItem_ExportGif");
|
||||
toolStripMenuItem_ExportGif.Click += toolStripMenuItem_ExportGif_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportWebp
|
||||
//
|
||||
toolStripMenuItem_ExportWebp.Name = "toolStripMenuItem_ExportWebp";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportWebp, "toolStripMenuItem_ExportWebp");
|
||||
toolStripMenuItem_ExportWebp.Click += toolStripMenuItem_ExportWebp_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportAvif
|
||||
//
|
||||
toolStripMenuItem_ExportAvif.Name = "toolStripMenuItem_ExportAvif";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportAvif, "toolStripMenuItem_ExportAvif");
|
||||
toolStripMenuItem_ExportAvif.Click += toolStripMenuItem_ExportAvif_Click;
|
||||
//
|
||||
// toolStripSeparator5
|
||||
//
|
||||
toolStripSeparator5.Name = "toolStripSeparator5";
|
||||
resources.ApplyResources(toolStripSeparator5, "toolStripSeparator5");
|
||||
//
|
||||
// toolStripMenuItem_ExportMp4
|
||||
//
|
||||
toolStripMenuItem_ExportMp4.Name = "toolStripMenuItem_ExportMp4";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMp4, "toolStripMenuItem_ExportMp4");
|
||||
toolStripMenuItem_ExportMp4.Click += toolStripMenuItem_ExportMp4_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportWebm
|
||||
//
|
||||
toolStripMenuItem_ExportWebm.Name = "toolStripMenuItem_ExportWebm";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportWebm, "toolStripMenuItem_ExportWebm");
|
||||
toolStripMenuItem_ExportWebm.Click += toolStripMenuItem_ExportWebm_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportMkv
|
||||
//
|
||||
toolStripMenuItem_ExportMkv.Name = "toolStripMenuItem_ExportMkv";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMkv, "toolStripMenuItem_ExportMkv");
|
||||
toolStripMenuItem_ExportMkv.Click += toolStripMenuItem_ExportMkv_Click;
|
||||
//
|
||||
// toolStripMenuItem_ExportMov
|
||||
//
|
||||
toolStripMenuItem_ExportMov.Name = "toolStripMenuItem_ExportMov";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportMov, "toolStripMenuItem_ExportMov");
|
||||
toolStripMenuItem_ExportMov.Click += toolStripMenuItem_ExportMov_Click;
|
||||
//
|
||||
// toolStripSeparator6
|
||||
//
|
||||
toolStripSeparator6.Name = "toolStripSeparator6";
|
||||
resources.ApplyResources(toolStripSeparator6, "toolStripSeparator6");
|
||||
//
|
||||
// toolStripMenuItem_ExportCustom
|
||||
//
|
||||
toolStripMenuItem_ExportCustom.Name = "toolStripMenuItem_ExportCustom";
|
||||
resources.ApplyResources(toolStripMenuItem_ExportCustom, "toolStripMenuItem_ExportCustom");
|
||||
toolStripMenuItem_ExportCustom.Click += toolStripMenuItem_ExportCustom_Click;
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2");
|
||||
//
|
||||
// toolStripMenuItem_Exit
|
||||
//
|
||||
toolStripMenuItem_Exit.Name = "toolStripMenuItem_Exit";
|
||||
resources.ApplyResources(toolStripMenuItem_Exit, "toolStripMenuItem_Exit");
|
||||
toolStripMenuItem_Exit.Click += toolStripMenuItem_Exit_Click;
|
||||
//
|
||||
// toolStripMenuItem_Texture
|
||||
//
|
||||
toolStripMenuItem_Texture.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ForceSmooth, toolStripMenuItem_ForceRepeated, toolStripMenuItem_ForceMipmap });
|
||||
toolStripMenuItem_Texture.Name = "toolStripMenuItem_Texture";
|
||||
resources.ApplyResources(toolStripMenuItem_Texture, "toolStripMenuItem_Texture");
|
||||
//
|
||||
// toolStripMenuItem_ForceSmooth
|
||||
//
|
||||
toolStripMenuItem_ForceSmooth.Name = "toolStripMenuItem_ForceSmooth";
|
||||
resources.ApplyResources(toolStripMenuItem_ForceSmooth, "toolStripMenuItem_ForceSmooth");
|
||||
toolStripMenuItem_ForceSmooth.Click += toolStripMenuItem_ForceSmooth_Click;
|
||||
//
|
||||
// toolStripMenuItem_ForceRepeated
|
||||
//
|
||||
toolStripMenuItem_ForceRepeated.Name = "toolStripMenuItem_ForceRepeated";
|
||||
resources.ApplyResources(toolStripMenuItem_ForceRepeated, "toolStripMenuItem_ForceRepeated");
|
||||
toolStripMenuItem_ForceRepeated.Click += toolStripMenuItem_ForceRepeated_Click;
|
||||
//
|
||||
// toolStripMenuItem_ForceMipmap
|
||||
//
|
||||
toolStripMenuItem_ForceMipmap.Name = "toolStripMenuItem_ForceMipmap";
|
||||
resources.ApplyResources(toolStripMenuItem_ForceMipmap, "toolStripMenuItem_ForceMipmap");
|
||||
toolStripMenuItem_ForceMipmap.Click += toolStripMenuItem_ForceMipmap_Click;
|
||||
//
|
||||
// toolStripMenuItem_Tool
|
||||
//
|
||||
toolStripMenuItem_Tool.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ConvertFileFormat });
|
||||
toolStripMenuItem_Tool.Name = "toolStripMenuItem_Tool";
|
||||
resources.ApplyResources(toolStripMenuItem_Tool, "toolStripMenuItem_Tool");
|
||||
//
|
||||
// toolStripMenuItem_ConvertFileFormat
|
||||
//
|
||||
toolStripMenuItem_ConvertFileFormat.Name = "toolStripMenuItem_ConvertFileFormat";
|
||||
resources.ApplyResources(toolStripMenuItem_ConvertFileFormat, "toolStripMenuItem_ConvertFileFormat");
|
||||
toolStripMenuItem_ConvertFileFormat.Click += toolStripMenuItem_ConvertFileFormat_Click;
|
||||
//
|
||||
// toolStripMenuItem_Download
|
||||
//
|
||||
toolStripMenuItem_Download.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ManageResource });
|
||||
toolStripMenuItem_Download.Name = "toolStripMenuItem_Download";
|
||||
resources.ApplyResources(toolStripMenuItem_Download, "toolStripMenuItem_Download");
|
||||
//
|
||||
// toolStripMenuItem_ManageResource
|
||||
//
|
||||
toolStripMenuItem_ManageResource.Name = "toolStripMenuItem_ManageResource";
|
||||
resources.ApplyResources(toolStripMenuItem_ManageResource, "toolStripMenuItem_ManageResource");
|
||||
toolStripMenuItem_ManageResource.Click += toolStripMenuItem_ManageResource_Click;
|
||||
//
|
||||
// toolStripMenuItem_Help
|
||||
//
|
||||
toolStripMenuItem_Help.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_Diagnostics, toolStripSeparator3, toolStripMenuItem_About, toolStripMenuItem_Debug });
|
||||
toolStripMenuItem_Help.Name = "toolStripMenuItem_Help";
|
||||
resources.ApplyResources(toolStripMenuItem_Help, "toolStripMenuItem_Help");
|
||||
//
|
||||
// toolStripMenuItem_Diagnostics
|
||||
//
|
||||
toolStripMenuItem_Diagnostics.Name = "toolStripMenuItem_Diagnostics";
|
||||
resources.ApplyResources(toolStripMenuItem_Diagnostics, "toolStripMenuItem_Diagnostics");
|
||||
toolStripMenuItem_Diagnostics.Click += toolStripMenuItem_Diagnostics_Click;
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3");
|
||||
//
|
||||
// toolStripMenuItem_About
|
||||
//
|
||||
toolStripMenuItem_About.Name = "toolStripMenuItem_About";
|
||||
resources.ApplyResources(toolStripMenuItem_About, "toolStripMenuItem_About");
|
||||
toolStripMenuItem_About.Click += toolStripMenuItem_About_Click;
|
||||
//
|
||||
// toolStripMenuItem_Debug
|
||||
//
|
||||
toolStripMenuItem_Debug.Name = "toolStripMenuItem_Debug";
|
||||
resources.ApplyResources(toolStripMenuItem_Debug, "toolStripMenuItem_Debug");
|
||||
toolStripMenuItem_Debug.Click += toolStripMenuItem_Debug_Click;
|
||||
//
|
||||
// toolStripMenuItem_Experiment
|
||||
//
|
||||
toolStripMenuItem_Experiment.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_DesktopProjection });
|
||||
toolStripMenuItem_Experiment.Name = "toolStripMenuItem_Experiment";
|
||||
resources.ApplyResources(toolStripMenuItem_Experiment, "toolStripMenuItem_Experiment");
|
||||
//
|
||||
// toolStripMenuItem_DesktopProjection
|
||||
//
|
||||
toolStripMenuItem_DesktopProjection.Name = "toolStripMenuItem_DesktopProjection";
|
||||
resources.ApplyResources(toolStripMenuItem_DesktopProjection, "toolStripMenuItem_DesktopProjection");
|
||||
toolStripMenuItem_DesktopProjection.Click += toolStripMenuItem_DesktopProjection_Click;
|
||||
//
|
||||
// ToolStripMenuItem_Language
|
||||
//
|
||||
ToolStripMenuItem_Language.DropDownItems.AddRange(new ToolStripItem[] { ToolStripMenuItem_English, ToolStripMenuItem_Chinese });
|
||||
ToolStripMenuItem_Language.Name = "ToolStripMenuItem_Language";
|
||||
resources.ApplyResources(ToolStripMenuItem_Language, "ToolStripMenuItem_Language");
|
||||
//
|
||||
// ToolStripMenuItem_English
|
||||
//
|
||||
ToolStripMenuItem_English.Name = "ToolStripMenuItem_English";
|
||||
resources.ApplyResources(ToolStripMenuItem_English, "ToolStripMenuItem_English");
|
||||
ToolStripMenuItem_English.Click += ToolStripMenuItem_English_Click;
|
||||
//
|
||||
// ToolStripMenuItem_Chinese
|
||||
//
|
||||
ToolStripMenuItem_Chinese.Name = "ToolStripMenuItem_Chinese";
|
||||
resources.ApplyResources(ToolStripMenuItem_Chinese, "ToolStripMenuItem_Chinese");
|
||||
ToolStripMenuItem_Chinese.Click += ToolStripMenuItem_Chinese_Click;
|
||||
//
|
||||
// panel_MainForm
|
||||
//
|
||||
panel_MainForm.Controls.Add(splitContainer_MainForm);
|
||||
panel_MainForm.Dock = DockStyle.Fill;
|
||||
panel_MainForm.Location = new Point(0, 32);
|
||||
resources.ApplyResources(panel_MainForm, "panel_MainForm");
|
||||
panel_MainForm.Name = "panel_MainForm";
|
||||
panel_MainForm.Padding = new Padding(10, 5, 10, 10);
|
||||
panel_MainForm.Size = new Size(1748, 1012);
|
||||
panel_MainForm.TabIndex = 4;
|
||||
//
|
||||
// toolTip
|
||||
//
|
||||
toolTip.ShowAlways = true;
|
||||
//
|
||||
// MainForm
|
||||
// SpineViewerForm
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(1748, 1044);
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Dpi;
|
||||
Controls.Add(panel_MainForm);
|
||||
Controls.Add(menuStrip);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MainMenuStrip = menuStrip;
|
||||
Margin = new Padding(3, 2, 3, 2);
|
||||
Name = "MainForm";
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "SpineViewer";
|
||||
Name = "SpineViewerForm";
|
||||
FormClosing += MainForm_FormClosing;
|
||||
Load += MainForm_Load;
|
||||
menuStrip.ResumeLayout(false);
|
||||
menuStrip.PerformLayout();
|
||||
splitContainer_MainForm.Panel1.ResumeLayout(false);
|
||||
splitContainer_MainForm.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_MainForm).EndInit();
|
||||
@@ -466,9 +507,11 @@
|
||||
splitContainer_Config.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_Config).EndInit();
|
||||
splitContainer_Config.ResumeLayout(false);
|
||||
groupBox_SkelConfig.ResumeLayout(false);
|
||||
groupBox_PreviewConfig.ResumeLayout(false);
|
||||
groupBox_SkelConfig.ResumeLayout(false);
|
||||
groupBox_Preview.ResumeLayout(false);
|
||||
menuStrip.ResumeLayout(false);
|
||||
menuStrip.PerformLayout();
|
||||
panel_MainForm.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
@@ -481,7 +524,6 @@
|
||||
private ToolStripMenuItem toolStripMenuItem_Open;
|
||||
private ToolStripMenuItem toolStripMenuItem_Exit;
|
||||
private ToolStripSeparator toolStripSeparator1;
|
||||
private ToolStripMenuItem toolStripMenuItem_Export;
|
||||
private ToolStripSeparator toolStripSeparator2;
|
||||
private RichTextBox rtbLog;
|
||||
private SplitContainer splitContainer_MainForm;
|
||||
@@ -489,7 +531,6 @@
|
||||
private SplitContainer splitContainer_Information;
|
||||
private GroupBox groupBox_SkelList;
|
||||
private GroupBox groupBox_SkelConfig;
|
||||
private SplitContainer splitContainer_Config;
|
||||
private GroupBox groupBox_PreviewConfig;
|
||||
private Panel panel_MainForm;
|
||||
private ToolStripMenuItem toolStripMenuItem_Help;
|
||||
@@ -497,18 +538,40 @@
|
||||
private ToolStripMenuItem toolStripMenuItem_BatchOpen;
|
||||
private GroupBox groupBox_Preview;
|
||||
private ToolTip toolTip;
|
||||
private PropertyGrid propertyGrid_Spine;
|
||||
private Controls.SpineListView spineListView;
|
||||
private PropertyGrid propertyGrid_Previewer;
|
||||
private Controls.SpinePreviewer spinePreviewer;
|
||||
private ToolStripMenuItem toolStripMenuItem_Function;
|
||||
private ToolStripMenuItem toolStripMenuItem_ResetAnimation;
|
||||
private Controls.SpinePreviewPanel spinePreviewPanel;
|
||||
private ToolStripMenuItem toolStripMenuItem_Diagnostics;
|
||||
private ToolStripSeparator toolStripSeparator3;
|
||||
private ToolStripMenuItem toolStripMenuItem_Download;
|
||||
private ToolStripMenuItem toolStripMenuItem_ManageResource;
|
||||
private ToolStripMenuItem toolStripMenuItem_Tool;
|
||||
private ToolStripMenuItem toolStripMenuItem_ConvertFileFormat;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportPreview;
|
||||
private ToolStripMenuItem toolStripMenuItem_Export;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportFrame;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportFrameSequence;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportGif;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportMp4;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportMov;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportMkv;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportWebm;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportCustom;
|
||||
private Controls.SpineViewPropertyGrid spineViewPropertyGrid;
|
||||
private ToolStripSeparator toolStripSeparator4;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportWebp;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportAvif;
|
||||
private ToolStripSeparator toolStripSeparator5;
|
||||
private ToolStripSeparator toolStripSeparator6;
|
||||
private SplitContainer splitContainer_Config;
|
||||
private ToolStripMenuItem toolStripMenuItem_Experiment;
|
||||
private ToolStripMenuItem toolStripMenuItem_DesktopProjection;
|
||||
private ToolStripMenuItem toolStripMenuItem_Debug;
|
||||
private ToolStripMenuItem ToolStripMenuItem_Language;
|
||||
private ToolStripMenuItem ToolStripMenuItem_English;
|
||||
private ToolStripMenuItem ToolStripMenuItem_Chinese;
|
||||
private ToolStripMenuItem toolStripMenuItem_Texture;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceSmooth;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceRepeated;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceMipmap;
|
||||
}
|
||||
}
|
||||
532
SpineViewer/Forms/SpineViewerForm.cs
Normal file
532
SpineViewer/Forms/SpineViewerForm.cs
Normal file
@@ -0,0 +1,532 @@
|
||||
using NLog;
|
||||
using SpineViewer.Spine;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Utils;
|
||||
using SpineViewer.Spine.SpineExporter;
|
||||
using System.Configuration;
|
||||
using SpineViewer.Utils.Localize;
|
||||
|
||||
namespace SpineViewer
|
||||
{
|
||||
internal partial class SpineViewerForm : Form
|
||||
{
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly Dictionary<string, Exporter> exporterCache = [];
|
||||
|
||||
public SpineViewerForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeLogConfiguration();
|
||||
|
||||
// 执行一些初始化工作
|
||||
try
|
||||
{
|
||||
SFMLShader.Init();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex.ToString());
|
||||
logger.Error("Failed to load fragment shader");
|
||||
MessagePopup.Warn(Properties.Resources.failLoadingFragmentShader, Properties.Resources.msgBoxWarning);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
toolStripMenuItem_Debug.Visible = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化窗口日志器
|
||||
/// </summary>
|
||||
private void InitializeLogConfiguration()
|
||||
{
|
||||
// 窗口日志
|
||||
var rtbTarget = new NLog.Windows.Forms.RichTextBoxTarget
|
||||
{
|
||||
Name = "rtbTarget",
|
||||
TargetForm = this,
|
||||
TargetRichTextBox = rtbLog,
|
||||
AutoScroll = true,
|
||||
MaxLines = 3000,
|
||||
SupportLinks = true,
|
||||
Layout = "[${level:format=OneLetter}]${date:format=yyyy-MM-dd HH\\:mm\\:ss} - ${message}"
|
||||
};
|
||||
|
||||
rtbTarget.WordColoringRules.Add(new("[D]", "Gray", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[I]", "DimGray", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[W]", "DarkOrange", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[E]", "Red", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[F]", "DarkRed", "Empty", FontStyle.Bold));
|
||||
|
||||
LogManager.Configuration.AddTarget(rtbTarget);
|
||||
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Fatal, rtbTarget);
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
|
||||
private void MainForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
spinePreviewPanel.StartRender();
|
||||
string cultureName = ConfigurationManager.AppSettings["localize"];
|
||||
switch (cultureName)
|
||||
{
|
||||
case "zh-CN":
|
||||
ToolStripMenuItem_Chinese.Checked = true;
|
||||
ToolStripMenuItem_English.Checked = false;
|
||||
break;
|
||||
case "en-US":
|
||||
ToolStripMenuItem_English.Checked = true;
|
||||
ToolStripMenuItem_Chinese.Checked = false;
|
||||
break;
|
||||
default:
|
||||
ToolStripMenuItem_Chinese.Checked = true;
|
||||
ToolStripMenuItem_English.Checked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
spinePreviewPanel.StopRender();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Open_Click(object sender, EventArgs e)
|
||||
{
|
||||
spineListView.Add();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_BatchOpen_Click(object sender, EventArgs e)
|
||||
{
|
||||
spineListView.BatchAdd();
|
||||
}
|
||||
|
||||
#region private void toolStripMenuItem_ExportXXX_Click(object sender, EventArgs e)
|
||||
|
||||
private void toolStripMenuItem_ExportFrame_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (spinePreviewPanel.IsUpdating && MessagePopup.Quest(Properties.Resources.isUpdatingAndManuallyExportFrame, Properties.Resources.msgBoxQuest) != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var k = nameof(toolStripMenuItem_ExportFrame);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new FrameExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new FrameExporterProperty((FrameExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportFrameSequence_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportFrameSequence);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new FrameSequenceExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new FrameSequenceExporterProperty((FrameSequenceExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportGif_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportGif);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new GifExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new GifExporterProperty((GifExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportWebp_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportWebp);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new WebpExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new WebpExporterProperty((WebpExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportAvif_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportAvif);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new AvifExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new AvifExporterProperty((AvifExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportMp4_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportMp4);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new Mp4Exporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new Mp4ExporterProperty((Mp4Exporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportWebm_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportWebm);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new WebmExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new WebmExporterProperty((WebmExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportMkv_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportMkv);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new MkvExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new MkvExporterProperty((MkvExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportMov_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportMov);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new MovExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new MovExporterProperty((MovExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportCustom_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportCustom);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new CustomExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new CustomExporterProperty((CustomExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ForceSmooth_Click(object sender, EventArgs e)
|
||||
{
|
||||
SpineObject.TextureLoader.ForceSmooth = !toolStripMenuItem_ForceSmooth.Checked;
|
||||
toolStripMenuItem_ForceSmooth.Checked = SpineObject.TextureLoader.ForceSmooth;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ForceRepeated_Click(object sender, EventArgs e)
|
||||
{
|
||||
SpineObject.TextureLoader.ForceRepeated = !toolStripMenuItem_ForceRepeated.Checked;
|
||||
toolStripMenuItem_ForceRepeated.Checked = SpineObject.TextureLoader.ForceRepeated;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ForceMipmap_Click(object sender, EventArgs e)
|
||||
{
|
||||
SpineObject.TextureLoader.ForceMipmap = !toolStripMenuItem_ForceMipmap.Checked;
|
||||
toolStripMenuItem_ForceMipmap.Checked = SpineObject.TextureLoader.ForceMipmap;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ConvertFileFormat_Click(object sender, EventArgs e)
|
||||
{
|
||||
var openDialog = new Dialogs.ConvertFileFormatDialog();
|
||||
if (openDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += ConvertFileFormat_Work;
|
||||
progressDialog.RunWorkerAsync(openDialog.Result);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ManageResource_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_About_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var dialog = new Dialogs.AboutDialog();
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Diagnostics_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var dialog = new Dialogs.DiagnosticsDialog();
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void splitContainer_SplitterMoved(object sender, SplitterEventArgs e) => ActiveControl = null;
|
||||
|
||||
private void splitContainer_MouseUp(object sender, MouseEventArgs e) => ActiveControl = null;
|
||||
|
||||
private void Export_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = (BackgroundWorker)sender;
|
||||
var exporter = (Exporter)e.Argument;
|
||||
Invoke(() => TaskbarManager.SetProgressState(Handle, TBPFLAG.TBPF_INDETERMINATE));
|
||||
spinePreviewPanel.StopRender();
|
||||
lock (spineListView.Spines) { exporter.Export(spineListView.Spines.Where(sp => !sp.IsHidden).ToArray(), (BackgroundWorker)sender); }
|
||||
e.Cancel = worker.CancellationPending;
|
||||
spinePreviewPanel.StartRender();
|
||||
Invoke(() => TaskbarManager.SetProgressState(Handle, TBPFLAG.TBPF_NOPROGRESS));
|
||||
}
|
||||
|
||||
private void ConvertFileFormat_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = sender as BackgroundWorker;
|
||||
var args = e.Argument as Dialogs.ConvertFileFormatDialogResult;
|
||||
var newSuffix = args.JsonTarget ? ".json" : ".skel";
|
||||
|
||||
int totalCount = args.SkelPaths.Length;
|
||||
int success = 0;
|
||||
int error = 0;
|
||||
|
||||
SkeletonConverter srcCvter = args.SourceVersion != SpineVersion.Auto ? SkeletonConverter.New(args.SourceVersion) : null;
|
||||
SkeletonConverter tgtCvter = SkeletonConverter.New(args.TargetVersion);
|
||||
|
||||
worker.ReportProgress(0, $"{Properties.Resources.process} 0/{totalCount}");
|
||||
for (int i = 0; i < totalCount; i++)
|
||||
{
|
||||
if (worker.CancellationPending)
|
||||
{
|
||||
e.Cancel = true;
|
||||
break;
|
||||
}
|
||||
|
||||
var skelPath = args.SkelPaths[i];
|
||||
var newPath = Path.ChangeExtension(skelPath, newSuffix);
|
||||
if (args.OutputDir is string outputDir) newPath = Path.Combine(outputDir, Path.GetFileName(newPath));
|
||||
|
||||
try
|
||||
{
|
||||
if (args.SourceVersion == SpineVersion.Auto)
|
||||
{
|
||||
try
|
||||
{
|
||||
srcCvter = SkeletonConverter.New(SpineUtils.GetVersion(skelPath));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidDataException($"Auto version detection failed for {skelPath}, try to use a specific version", ex);
|
||||
}
|
||||
}
|
||||
var root = srcCvter.Read(skelPath);
|
||||
root = srcCvter.ToVersion(root, args.TargetVersion);
|
||||
if (args.JsonTarget) tgtCvter.WriteJson(root, newPath);
|
||||
else tgtCvter.WriteBinary(root, newPath);
|
||||
success++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex.ToString());
|
||||
logger.Error("Failed to convert {}", skelPath);
|
||||
error++;
|
||||
}
|
||||
|
||||
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"{Properties.Resources.process} {i + 1}/{totalCount}");
|
||||
}
|
||||
|
||||
if (error > 0)
|
||||
{
|
||||
logger.Warn("Batch convert {} successfully, {} failed", success, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("{} skel converted successfully", success);
|
||||
}
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_DesktopProjection_Click(object sender, EventArgs e)
|
||||
{
|
||||
toolStripMenuItem_DesktopProjection.Checked = !toolStripMenuItem_DesktopProjection.Checked;
|
||||
spinePreviewPanel.EnableDesktopProjection = toolStripMenuItem_DesktopProjection.Checked;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Debug_Click(object sender, EventArgs e)
|
||||
{
|
||||
#if DEBUG
|
||||
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
||||
//var root = cvt.ReadBinary(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3 - 副本.skel");
|
||||
//cvt.WriteJson(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
||||
|
||||
//root = cvt.ReadJson(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
||||
//cvt.WriteBinary(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
||||
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
||||
|
||||
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
||||
//var root = cvt.ReadJson(@"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.json");
|
||||
//cvt.WriteBinary(root, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
||||
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
||||
//_Test();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void ToolStripMenuItem_English_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (ToolStripMenuItem_English.Checked) return;
|
||||
ChangeLanguage("en-US");
|
||||
}
|
||||
|
||||
private void ToolStripMenuItem_Chinese_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (ToolStripMenuItem_Chinese.Checked) return;
|
||||
ChangeLanguage("zh-CN");
|
||||
}
|
||||
|
||||
private void ChangeLanguage(string localize)
|
||||
{
|
||||
DialogResult result = MessageBox.Show(
|
||||
Properties.Resources.restartPrompt,
|
||||
Properties.Resources.restartTitle,
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Question);
|
||||
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
LocalizeConfiguration.UpdateLocalizeSetting(localize);
|
||||
LocalizeConfiguration.SetCulture();
|
||||
Application.Restart();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
//private void spinePreviewer_KeyDown(object sender, KeyEventArgs e)
|
||||
//{
|
||||
// switch (e.KeyCode)
|
||||
// {
|
||||
// case Keys.Space:
|
||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||
// spinePreviewer.ClickStopButton();
|
||||
// else
|
||||
// spinePreviewer.ClickStartButton();
|
||||
// break;
|
||||
// case Keys.Right:
|
||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||
// spinePreviewer.ClickForwardFastButton();
|
||||
// else
|
||||
// spinePreviewer.ClickForwardStepButton();
|
||||
// break;
|
||||
// case Keys.Left:
|
||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||
// spinePreviewer.ClickRestartButton();
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
3562
SpineViewer/Forms/SpineViewerForm.en.resx
Normal file
3562
SpineViewer/Forms/SpineViewerForm.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
4326
SpineViewer/Forms/SpineViewerForm.resx
Normal file
4326
SpineViewer/Forms/SpineViewerForm.resx
Normal file
File diff suppressed because it is too large
Load Diff
51
SpineViewer/Forms/WallpaperForm.Designer.cs
generated
Normal file
51
SpineViewer/Forms/WallpaperForm.Designer.cs
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace SpineViewer
|
||||
{
|
||||
partial class WallpaperForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
SuspendLayout();
|
||||
//
|
||||
// WallpaperForm
|
||||
//
|
||||
AutoScaleMode = AutoScaleMode.None;
|
||||
ClientSize = new Size(512, 512);
|
||||
ControlBox = false;
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "WallpaperForm";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
WindowState = FormWindowState.Minimized;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
73
SpineViewer/Forms/WallpaperForm.cs
Normal file
73
SpineViewer/Forms/WallpaperForm.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using SpineViewer.Natives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer
|
||||
{
|
||||
[ToolboxItem(true)]
|
||||
[Designer(typeof(ComponentDesigner), typeof(IDesigner))]
|
||||
[DesignTimeVisible(true)]
|
||||
public partial class WallpaperForm: Form
|
||||
{
|
||||
public WallpaperForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
var cp = base.CreateParams;
|
||||
cp.ExStyle |= Win32.WS_EX_TOOLWINDOW | Win32.WS_EX_LAYERED;
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
// 设置成嵌入桌面
|
||||
var progman = Win32.FindWindow("Progman", null);
|
||||
if (progman != IntPtr.Zero)
|
||||
{
|
||||
// 确保 WorkerW 被创建
|
||||
Win32.SendMessageTimeout(progman, Win32.WM_SPAWN_WORKER, IntPtr.Zero, IntPtr.Zero, Win32.SMTO_NORMAL, 1000, out _);
|
||||
var workerW = Win32.GetWorkerW();
|
||||
if (workerW != IntPtr.Zero)
|
||||
{
|
||||
Win32.SetLayeredWindowAttributes(Handle, 0, 255, Win32.LWA_ALPHA);
|
||||
Win32.SetParent(Handle, workerW); // 嵌入之前必须保证有 WS_EX_LAYERED 标志
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public byte LayeredWindowAlpha
|
||||
{
|
||||
get
|
||||
{
|
||||
uint crKey = 0;
|
||||
byte bAlpha = 255;
|
||||
uint dwFlags = Win32.LWA_ALPHA;
|
||||
Win32.GetLayeredWindowAttributes(Handle, ref crKey, ref bAlpha, ref dwFlags);
|
||||
return bAlpha;
|
||||
}
|
||||
set
|
||||
{
|
||||
Win32.SetLayeredWindowAttributes(Handle, 0, value, Win32.LWA_ALPHA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
SpineViewer/Forms/WallpaperForm.resx
Normal file
120
SpineViewer/Forms/WallpaperForm.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -1,435 +0,0 @@
|
||||
using FFMpegCore.Pipes;
|
||||
using FFMpegCore;
|
||||
using NLog;
|
||||
using SFML.System;
|
||||
using SpineViewer.Spine;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using FFMpegCore.Enums;
|
||||
|
||||
namespace SpineViewer
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeLogConfiguration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化窗口日志器
|
||||
/// </summary>
|
||||
private void InitializeLogConfiguration()
|
||||
{
|
||||
// 窗口日志
|
||||
var rtbTarget = new NLog.Windows.Forms.RichTextBoxTarget
|
||||
{
|
||||
Name = "rtbTarget",
|
||||
TargetForm = this,
|
||||
TargetRichTextBox = rtbLog,
|
||||
AutoScroll = true,
|
||||
MaxLines = 3000,
|
||||
SupportLinks = true,
|
||||
Layout = "[${level:format=OneLetter}]${date:format=yyyy-MM-dd HH\\:mm\\:ss} - ${message}"
|
||||
};
|
||||
|
||||
rtbTarget.WordColoringRules.Add(new("[D]", "Gray", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[I]", "DimGray", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[W]", "DarkOrange", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[E]", "Red", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[F]", "DarkRed", "Empty", FontStyle.Bold));
|
||||
|
||||
LogManager.Configuration.AddTarget(rtbTarget);
|
||||
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Fatal, rtbTarget);
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
|
||||
private void MainForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
spinePreviewer.StartPreview();
|
||||
}
|
||||
|
||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
spinePreviewer.StopPreview();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Open_Click(object sender, EventArgs e)
|
||||
{
|
||||
spineListView.Add();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_BatchOpen_Click(object sender, EventArgs e)
|
||||
{
|
||||
spineListView.BatchAdd();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Export_Click(object sender, EventArgs e)
|
||||
{
|
||||
// TODO: 改成统一导出调用
|
||||
lock (spineListView.Spines)
|
||||
{
|
||||
if (spineListView.Spines.Count <= 0)
|
||||
{
|
||||
MessageBox.Info("请至少打开一个骨骼文件");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var exportDialog = new Dialogs.ExportPngDialog();
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += ExportPng_Work;
|
||||
progressDialog.RunWorkerAsync(exportDialog);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportPreview_Click(object sender, EventArgs e)
|
||||
{
|
||||
lock (spineListView.Spines)
|
||||
{
|
||||
if (spineListView.Spines.Count <= 0)
|
||||
{
|
||||
MessageBox.Info("请至少打开一个骨骼文件");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var saveDialog = new Dialogs.ExportPreviewDialog();
|
||||
if (saveDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += ExportPreview_Work;
|
||||
progressDialog.RunWorkerAsync(saveDialog.Result);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ResetAnimation_Click(object sender, EventArgs e)
|
||||
{
|
||||
lock (spineListView.Spines)
|
||||
{
|
||||
foreach (var spine in spineListView.Spines)
|
||||
spine.CurrentAnimation = spine.CurrentAnimation;
|
||||
}
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ConvertFileFormat_Click(object sender, EventArgs e)
|
||||
{
|
||||
var openDialog = new Dialogs.ConvertFileFormatDialog();
|
||||
if (openDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += ConvertFileFormat_Work;
|
||||
progressDialog.RunWorkerAsync(openDialog.Result);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
//IEnumerable<IVideoFrame> testExport(int fps)
|
||||
//{
|
||||
// var duration = 2f;
|
||||
// var resolution = spinePreviewer.Resolution;
|
||||
// var delta = 1f / fps;
|
||||
// var frameCount = 1 + (int)(duration / delta); // 零帧开始导出
|
||||
|
||||
// var spinesReverse = spineListView.Spines.Reverse();
|
||||
|
||||
// // 重置动画时间
|
||||
// foreach (var spine in spinesReverse)
|
||||
// spine.CurrentAnimation = spine.CurrentAnimation;
|
||||
|
||||
// // 逐帧导出
|
||||
// var success = 0;
|
||||
// for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
|
||||
// {
|
||||
// using var tex = new SFML.Graphics.RenderTexture((uint)resolution.Width, (uint)resolution.Height);
|
||||
// tex.SetView(spinePreviewer.View);
|
||||
// tex.Clear(SFML.Graphics.Color.Transparent);
|
||||
|
||||
// foreach (var spine in spinesReverse)
|
||||
// {
|
||||
// tex.Draw(spine);
|
||||
// spine.Update(delta);
|
||||
// }
|
||||
|
||||
// tex.Display();
|
||||
// Debug.WriteLine($"ThreadID: {Environment.CurrentManagedThreadId}");
|
||||
// var frame = tex.Texture.CopyToFrame();
|
||||
// tex.Dispose();
|
||||
// yield return frame;
|
||||
|
||||
// success++;
|
||||
// }
|
||||
|
||||
// Program.Logger.Info("Exporting done: {}/{}", success, frameCount);
|
||||
//}
|
||||
|
||||
private void toolStripMenuItem_ManageResource_Click(object sender, EventArgs e)
|
||||
{
|
||||
//spinePreviewer.StopPreview();
|
||||
|
||||
//lock (spineListView.Spines)
|
||||
//{
|
||||
// //var fps = 24;
|
||||
// ////foreach (var i in testExport(fps))
|
||||
// //// _ = i;
|
||||
// ////var t = testExport(fps).ToArray();
|
||||
// ////var a = testExport(fps).GetEnumerator();
|
||||
// ////while (a.MoveNext());
|
||||
// //var videoFramesSource = new RawVideoPipeSource(testExport(fps)) { FrameRate = fps };
|
||||
// //var outputPath = @"C:\Users\ljh\Desktop\test\a.mov";
|
||||
// //var task = FFMpegArguments
|
||||
// // .FromPipeInput(videoFramesSource)
|
||||
// // .OutputToFile(outputPath, true
|
||||
// // , options => options
|
||||
// // //.WithCustomArgument("-vf \"split[s0][s1];[s0]palettegen=reserve_transparent=1[p];[s1][p]paletteuse=alpha_threshold=128\""))
|
||||
// // .WithCustomArgument("-c:v prores_ks -profile:v 4444 -pix_fmt yuva444p10le"))
|
||||
// // .ProcessAsynchronously();
|
||||
// //task.Wait();
|
||||
//}
|
||||
|
||||
//spinePreviewer.StartPreview();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_About_Click(object sender, EventArgs e)
|
||||
{
|
||||
(new Dialogs.AboutDialog()).ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Diagnostics_Click(object sender, EventArgs e)
|
||||
{
|
||||
(new Dialogs.DiagnosticsDialog()).ShowDialog();
|
||||
}
|
||||
|
||||
private void splitContainer_SplitterMoved(object sender, SplitterEventArgs e) => ActiveControl = null;
|
||||
|
||||
private void splitContainer_MouseUp(object sender, MouseEventArgs e) => ActiveControl = null;
|
||||
|
||||
private void propertyGrid_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e) => (sender as PropertyGrid)?.Refresh();
|
||||
|
||||
private void spinePreviewer_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
propertyGrid_Spine.Refresh();
|
||||
}
|
||||
|
||||
private void ExportPng_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = sender as BackgroundWorker;
|
||||
var arguments = e.Argument as Dialogs.ExportPngDialog;
|
||||
var outputDir = arguments.OutputDir;
|
||||
var duration = arguments.Duration;
|
||||
var fps = arguments.Fps;
|
||||
var timestamp = DateTime.Now.ToString("yyMMddHHmmss");
|
||||
|
||||
var frameArgs = spinePreviewer.GetFrameArgs();
|
||||
var renderSelectedOnly = spinePreviewer.RenderSelectedOnly;
|
||||
|
||||
var resolution = frameArgs.Resolution;
|
||||
var tex = new SFML.Graphics.RenderTexture((uint)resolution.Width, (uint)resolution.Height);
|
||||
tex.SetView(frameArgs.View);
|
||||
var delta = 1f / fps;
|
||||
var frameCount = 1 + (int)(duration / delta); // 零帧开始导出
|
||||
|
||||
spinePreviewer.StopPreview();
|
||||
|
||||
lock (spineListView.Spines)
|
||||
{
|
||||
var spinesReverse = spineListView.Spines.Reverse();
|
||||
|
||||
// 重置动画时间
|
||||
foreach (var spine in spinesReverse)
|
||||
spine.CurrentAnimation = spine.CurrentAnimation;
|
||||
|
||||
Program.Logger.Info(
|
||||
"Begin exporting png frames to output dir {}, duration: {}, fps: {}, totally {} spines",
|
||||
[outputDir, duration, fps, spinesReverse.Count()]
|
||||
);
|
||||
|
||||
// 逐帧导出
|
||||
var success = 0;
|
||||
worker.ReportProgress(0, $"已处理 0/{frameCount}");
|
||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
|
||||
{
|
||||
if (worker.CancellationPending)
|
||||
break;
|
||||
|
||||
tex.Clear(SFML.Graphics.Color.Transparent);
|
||||
|
||||
foreach (var spine in spinesReverse)
|
||||
{
|
||||
if (renderSelectedOnly && !spine.IsSelected)
|
||||
continue;
|
||||
|
||||
tex.Draw(spine);
|
||||
spine.Update(delta);
|
||||
}
|
||||
|
||||
tex.Display();
|
||||
using (var img = tex.Texture.CopyToImage())
|
||||
{
|
||||
img.SaveToFile(Path.Combine(outputDir, $"{timestamp}_{fps}_{frameIndex:d6}.png"));
|
||||
}
|
||||
|
||||
success++;
|
||||
worker.ReportProgress((int)((frameIndex + 1) * 100.0) / frameCount, $"已处理 {frameIndex + 1}/{frameCount}");
|
||||
}
|
||||
|
||||
Program.Logger.Info("Exporting done: {}/{}", success, frameCount);
|
||||
}
|
||||
|
||||
spinePreviewer.StartPreview();
|
||||
}
|
||||
|
||||
private void ExportPreview_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = sender as BackgroundWorker;
|
||||
var arguments = e.Argument as Dialogs.ExportPreviewDialogResult;
|
||||
|
||||
var outputDir = arguments.OutputDir;
|
||||
var imageFormat = arguments.ImageFormat;
|
||||
var resolution = arguments.Resolution;
|
||||
var padding = arguments.Padding;
|
||||
var dpi = arguments.DPI;
|
||||
var renderSelectedOnly = spinePreviewer.RenderSelectedOnly;
|
||||
|
||||
var tex = new SFML.Graphics.RenderTexture((uint)resolution.Width, (uint)resolution.Height);
|
||||
|
||||
int success = 0;
|
||||
int error = 0;
|
||||
spinePreviewer.StopPreview();
|
||||
lock (spineListView.Spines)
|
||||
{
|
||||
var spines = spineListView.Spines;
|
||||
int totalCount = spines.Count;
|
||||
worker.ReportProgress(0, $"已处理 0/{totalCount}");
|
||||
for (int i = 0; i < totalCount; i++)
|
||||
{
|
||||
if (worker.CancellationPending)
|
||||
{
|
||||
e.Cancel = true;
|
||||
break;
|
||||
}
|
||||
|
||||
var spine = spines[i];
|
||||
if (renderSelectedOnly && !spine.IsSelected)
|
||||
continue;
|
||||
|
||||
var filename = $"(preview) {spine.Name}{imageFormat.GetSuffix()}"; // 加上 preview 是为了防止覆盖同名的 png 文件
|
||||
var savePath = outputDir is null ? Path.Combine(spine.AssetsDir, filename) : Path.Combine(outputDir, filename);
|
||||
|
||||
var tmp = spine.CurrentAnimation;
|
||||
spine.CurrentAnimation = Spine.Spine.EMPTY_ANIMATION;
|
||||
tex.SetView(spine.GetInitView(resolution, padding));
|
||||
tex.Clear(SFML.Graphics.Color.Transparent);
|
||||
tex.Draw(spine);
|
||||
tex.Display();
|
||||
spine.CurrentAnimation = tmp;
|
||||
|
||||
try
|
||||
{
|
||||
using (var img = new Bitmap(tex.Texture.CopyToBitmap()))
|
||||
{
|
||||
img.SetResolution(dpi.Width, dpi.Height);
|
||||
img.Save(savePath, imageFormat);
|
||||
}
|
||||
success++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Logger.Error(ex.ToString());
|
||||
Program.Logger.Error("Failed to save preview {}", spine.SkelPath);
|
||||
error++;
|
||||
}
|
||||
|
||||
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"已处理 {i + 1}/{totalCount}");
|
||||
}
|
||||
}
|
||||
spinePreviewer.StartPreview();
|
||||
|
||||
if (error > 0)
|
||||
{
|
||||
Program.Logger.Warn("Preview save {} successfully, {} failed", success, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
Program.Logger.Info("{} preview saved successfully", success);
|
||||
}
|
||||
|
||||
Program.LogCurrentMemoryUsage();
|
||||
}
|
||||
|
||||
private void ConvertFileFormat_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = sender as BackgroundWorker;
|
||||
var arguments = e.Argument as Dialogs.ConvertFileFormatDialogResult;
|
||||
var skelPaths = arguments.SkelPaths;
|
||||
var srcVersion = arguments.SourceVersion;
|
||||
var tgtVersion = arguments.TargetVersion;
|
||||
var jsonTarget = arguments.JsonTarget;
|
||||
var newSuffix = jsonTarget ? ".json" : ".skel";
|
||||
|
||||
int totalCount = skelPaths.Length;
|
||||
int success = 0;
|
||||
int error = 0;
|
||||
|
||||
SkeletonConverter srcCvter = srcVersion != Spine.Version.Auto ? SkeletonConverter.New(srcVersion) : null;
|
||||
SkeletonConverter tgtCvter = SkeletonConverter.New(tgtVersion);
|
||||
|
||||
worker.ReportProgress(0, $"已处理 0/{totalCount}");
|
||||
for (int i = 0; i < totalCount; i++)
|
||||
{
|
||||
if (worker.CancellationPending)
|
||||
{
|
||||
e.Cancel = true;
|
||||
break;
|
||||
}
|
||||
|
||||
var skelPath = skelPaths[i];
|
||||
var newPath = Path.ChangeExtension(skelPath, newSuffix);
|
||||
|
||||
try
|
||||
{
|
||||
if (srcVersion == Spine.Version.Auto)
|
||||
{
|
||||
if (Spine.Spine.GetVersion(skelPath) is Spine.Version detectedSrcVersion)
|
||||
srcCvter = SkeletonConverter.New(detectedSrcVersion);
|
||||
else
|
||||
throw new InvalidDataException($"Auto version detection failed for {skelPath}, try to use a specific version");
|
||||
}
|
||||
var root = srcCvter.Read(skelPath);
|
||||
root = srcCvter.ToVersion(root, tgtVersion);
|
||||
if (jsonTarget) tgtCvter.WriteJson(root, newPath); else tgtCvter.WriteBinary(root, newPath);
|
||||
success++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Logger.Error(ex.ToString());
|
||||
Program.Logger.Error("Failed to convert {}", skelPath);
|
||||
error++;
|
||||
}
|
||||
|
||||
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"已处理 {i + 1}/{totalCount}");
|
||||
}
|
||||
|
||||
if (error > 0)
|
||||
{
|
||||
Program.Logger.Warn("Batch convert {} successfully, {} failed", success, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
Program.Logger.Info("{} skel converted successfully", success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
SpineViewer/Natives/TaskbarManager.cs
Normal file
65
SpineViewer/Natives/TaskbarManager.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Natives
|
||||
{
|
||||
internal enum TBPFLAG
|
||||
{
|
||||
TBPF_NOPROGRESS = 0,
|
||||
TBPF_INDETERMINATE = 0x1,
|
||||
TBPF_NORMAL = 0x2,
|
||||
TBPF_ERROR = 0x4,
|
||||
TBPF_PAUSED = 0x8
|
||||
}
|
||||
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[ComImport, Guid("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
|
||||
internal interface ITaskbarList3
|
||||
{
|
||||
// ITaskbarList
|
||||
void HrInit();
|
||||
void AddTab(nint hwnd);
|
||||
void DeleteTab(nint hwnd);
|
||||
void ActivateTab(nint hwnd);
|
||||
void SetActiveAlt(nint hwnd);
|
||||
// ITaskbarList2
|
||||
void MarkFullscreenWindow(nint hwnd, [MarshalAs(UnmanagedType.Bool)] bool fFullscreen);
|
||||
// ITaskbarList3
|
||||
void SetProgressValue(nint hwnd, ulong ullCompleted, ulong ullTotal);
|
||||
void SetProgressState(nint hwnd, TBPFLAG tbpFlags);
|
||||
//void RegisterTab(IntPtr hwndTab, IntPtr hwndMDI);
|
||||
//void UnregisterTab(IntPtr hwndTab);
|
||||
//void SetTabOrder(IntPtr hwndTab, IntPtr hwndInsertBefore);
|
||||
//void SetTabActive(IntPtr hwndTab, IntPtr hwndMDI, uint dwReserved);
|
||||
//void ThumbBarAddButtons(IntPtr hwnd, uint cButtons, THUMBBUTTON[] pButton);
|
||||
//void ThumbBarUpdateButtons(IntPtr hwnd, uint cButtons, THUMBBUTTON[] pButton);
|
||||
//void ThumbBarSetImageList(IntPtr hwnd, IntPtr himl);
|
||||
//void SetOverlayIcon(IntPtr hwnd, IntPtr hIcon, string pszDescription);
|
||||
//void SetThumbnailTooltip(IntPtr hwnd, string pszTip);
|
||||
//void SetThumbnailClip(IntPtr hwnd, ref RECT prcClip);
|
||||
}
|
||||
|
||||
[ComImport, Guid("56FDF344-FD6D-11d0-958A-006097C9A090")]
|
||||
internal class TaskbarList { }
|
||||
|
||||
internal static class TaskbarManager
|
||||
{
|
||||
private static readonly ITaskbarList3 taskbarList = (ITaskbarList3)new TaskbarList();
|
||||
|
||||
static TaskbarManager()
|
||||
{
|
||||
taskbarList.HrInit();
|
||||
}
|
||||
|
||||
public static void SetProgressState(nint windowHandle, TBPFLAG state)
|
||||
{
|
||||
taskbarList.SetProgressState(windowHandle, state);
|
||||
}
|
||||
|
||||
public static void SetProgressValue(nint windowHandle, ulong completed, ulong total)
|
||||
{
|
||||
taskbarList.SetProgressValue(windowHandle, completed, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
205
SpineViewer/Natives/Win32.cs
Normal file
205
SpineViewer/Natives/Win32.cs
Normal file
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpineViewer.Natives
|
||||
{
|
||||
/// <summary>
|
||||
/// Win32 Sdk 包装类
|
||||
/// </summary>
|
||||
public static class Win32
|
||||
{
|
||||
public const int GWL_STYLE = -16;
|
||||
public const int WS_SIZEBOX = 0x40000;
|
||||
public const int WS_BORDER = 0x800000;
|
||||
public const int WS_VISIBLE = 0x10000000;
|
||||
public const int WS_CHILD = 0x40000000;
|
||||
public const int WS_POPUP = unchecked((int)0x80000000);
|
||||
|
||||
public const int GWL_EXSTYLE = -20;
|
||||
public const int WS_EX_TOPMOST = 0x8;
|
||||
public const int WS_EX_TRANSPARENT = 0x20;
|
||||
public const int WS_EX_TOOLWINDOW = 0x80;
|
||||
public const int WS_EX_WINDOWEDGE = 0x100;
|
||||
public const int WS_EX_CLIENTEDGE = 0x200;
|
||||
public const int WS_EX_APPWINDOW = 0x40000;
|
||||
public const int WS_EX_LAYERED = 0x80000;
|
||||
public const int WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE;
|
||||
public const int WS_EX_NOACTIVATE = 0x8000000;
|
||||
|
||||
public const uint LWA_COLORKEY = 0x1;
|
||||
public const uint LWA_ALPHA = 0x2;
|
||||
|
||||
public const byte AC_SRC_OVER = 0x00;
|
||||
public const byte AC_SRC_ALPHA = 0x01;
|
||||
|
||||
public const int ULW_COLORKEY = 0x00000001;
|
||||
public const int ULW_ALPHA = 0x00000002;
|
||||
public const int ULW_OPAQUE = 0x00000004;
|
||||
|
||||
public const nint HWND_TOPMOST = -1;
|
||||
|
||||
public const uint SWP_NOSIZE = 0x0001;
|
||||
public const uint SWP_NOMOVE = 0x0002;
|
||||
public const uint SWP_NOZORDER = 0x0004;
|
||||
public const uint SWP_FRAMECHANGED = 0x0020;
|
||||
|
||||
public const int WM_SPAWN_WORKER = 0x052C; // 一个未公开的神秘消息
|
||||
|
||||
public const uint SMTO_NORMAL = 0x0000;
|
||||
public const uint SMTO_BLOCK = 0x0001;
|
||||
public const uint SMTO_ABORTIFHUNG = 0x0002;
|
||||
public const uint SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;
|
||||
|
||||
public const uint GA_PARENT = 1;
|
||||
|
||||
public const uint GW_OWNER = 4;
|
||||
|
||||
public const int SW_HIDE = 0;
|
||||
public const int SW_SHOWNORMAL = 1;
|
||||
public const int SW_SHOWMINIMIZED = 2;
|
||||
public const int SW_SHOWMAXIMIZED = 3;
|
||||
public const int SW_SHOWNOACTIVATE = 4;
|
||||
public const int SW_SHOW = 5;
|
||||
public const int SW_MINIMIZE = 6;
|
||||
public const int SW_SHOWMINNOACTIVE = 7;
|
||||
public const int SW_SHOWNA = 8;
|
||||
public const int SW_RESTORE = 9;
|
||||
public const int SW_SHOWDEFAULT = 10;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SIZE
|
||||
{
|
||||
public int cx;
|
||||
public int cy;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct BLENDFUNCTION
|
||||
{
|
||||
public byte BlendOp;
|
||||
public byte BlendFlags;
|
||||
public byte SourceConstantAlpha;
|
||||
public byte AlphaFormat;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct LASTINPUTINFO
|
||||
{
|
||||
public uint cbSize;
|
||||
public uint dwTime;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern nint GetDC(nint hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern int ReleaseDC(nint hWnd, nint hDC);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern int SetWindowLong(nint hWnd, int nIndex, int dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern int GetWindowLong(nint hWnd, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool GetLayeredWindowAttributes(nint hWnd, ref uint crKey, ref byte bAlpha, ref uint dwFlags);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool SetLayeredWindowAttributes(nint hWnd, uint pcrKey, byte pbAlpha, uint pdwFlags);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool UpdateLayeredWindow(nint hWnd, nint hdcDst, nint pptDst, ref SIZE psize, nint hdcSrc, ref POINT pptSrc, int crKey, ref BLENDFUNCTION pblend, int dwFlags);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool SetWindowPos(nint hWnd, nint hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern uint GetDoubleClickTime();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern nint FindWindow(string lpClassName, string lpWindowName);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern nint SendMessageTimeout(nint hWnd, uint Msg, nint wParam, nint lParam, uint fuFlags, uint uTimeout, out nint lpdwResult);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern nint FindWindowEx(nint parentHandle, nint childAfter, string className, string windowTitle);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern nint SetParent(nint hWndChild, nint hWndNewParent);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern nint GetParent(nint hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern nint GetAncestor(nint hWnd, uint gaFlags);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern nint GetWindow(nint hWnd, uint uCmd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool ShowWindow(nint hWnd, int nCmdShow);
|
||||
|
||||
[DllImport("gdi32.dll", SetLastError = true)]
|
||||
public static extern nint CreateCompatibleDC(nint hdc);
|
||||
|
||||
[DllImport("gdi32.dll", SetLastError = true)]
|
||||
public static extern bool DeleteDC(nint hdc);
|
||||
|
||||
[DllImport("gdi32.dll", SetLastError = true)]
|
||||
public static extern nint SelectObject(nint hdc, nint hgdiobj);
|
||||
|
||||
[DllImport("gdi32.dll", SetLastError = true)]
|
||||
public static extern bool DeleteObject(nint hObject);
|
||||
|
||||
public static TimeSpan GetLastInputElapsedTime()
|
||||
{
|
||||
LASTINPUTINFO lastInputInfo = new();
|
||||
lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
|
||||
|
||||
uint idleTimeMillis = 1000;
|
||||
if (GetLastInputInfo(ref lastInputInfo))
|
||||
{
|
||||
uint tickCount = (uint)Environment.TickCount;
|
||||
uint lastInputTick = lastInputInfo.dwTime;
|
||||
idleTimeMillis = tickCount - lastInputTick;
|
||||
}
|
||||
return TimeSpan.FromMilliseconds(idleTimeMillis);
|
||||
}
|
||||
|
||||
public static nint GetWorkerW()
|
||||
{
|
||||
var progman = FindWindow("Progman", null);
|
||||
if (progman == nint.Zero)
|
||||
return nint.Zero;
|
||||
nint hWnd = FindWindowEx(progman, 0, "WorkerW", null);
|
||||
Debug.WriteLine($"HWND(Progman.WorkerW): {hWnd:x8}");
|
||||
return hWnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,42 @@
|
||||
using NLog;
|
||||
using SpineViewer.Spine.Implementations.SkeletonConverter;
|
||||
using SpineViewer.Utils;
|
||||
using SpineViewer.Utils.Localize;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace SpineViewer
|
||||
{
|
||||
internal static class Program
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序路径
|
||||
/// </summary>
|
||||
public static readonly string FilePath = Environment.ProcessPath;
|
||||
///// <summary>
|
||||
///// 程序路径
|
||||
///// </summary>
|
||||
//public static readonly string FilePath = Environment.ProcessPath;
|
||||
|
||||
/// <summary>
|
||||
/// 程序名
|
||||
/// </summary>
|
||||
public static readonly string Name = Path.GetFileNameWithoutExtension(FilePath);
|
||||
///// <summary>
|
||||
///// 程序名
|
||||
///// </summary>
|
||||
//public static readonly string Name = Path.GetFileNameWithoutExtension(FilePath);
|
||||
|
||||
/// <summary>
|
||||
/// 程序目录
|
||||
/// </summary>
|
||||
public static readonly string RootDir = Path.GetDirectoryName(FilePath);
|
||||
///// <summary>
|
||||
///// 程序目录
|
||||
///// </summary>
|
||||
//public static readonly string RootDir = Path.GetDirectoryName(FilePath);
|
||||
|
||||
/// <summary>
|
||||
/// 程序临时目录
|
||||
/// </summary>
|
||||
public static readonly string TempDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Name)).FullName;
|
||||
///// <summary>
|
||||
///// 程序临时目录
|
||||
///// </summary>
|
||||
//public static readonly string TempDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), Name)).FullName;
|
||||
|
||||
/// <summary>
|
||||
/// 程序进程
|
||||
/// </summary>
|
||||
public static readonly Process Process = Process.GetCurrentProcess();
|
||||
public static string Version => Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
|
||||
/// <summary>
|
||||
/// 程序日志器
|
||||
/// </summary>
|
||||
public static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 应用入口点
|
||||
@@ -41,21 +44,23 @@ namespace SpineViewer
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
// 此处先初始化全局配置再触发静态字段 Logger 引用构造, 才能将配置应用到新的日志器上
|
||||
InitializeLogConfiguration();
|
||||
Logger.Info("Program Started");
|
||||
logger.Info("Program Started");
|
||||
|
||||
// To customize application configuration such as set high DPI settings or default font,
|
||||
// see https://aka.ms/applicationconfiguration.
|
||||
ApplicationConfiguration.Initialize();
|
||||
LocalizeConfiguration.SetCulture();
|
||||
|
||||
try
|
||||
{
|
||||
Application.Run(new MainForm());
|
||||
Application.Run(new SpineViewerForm() { Text = $"SpineViewer - v{Version}" });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Fatal(ex.ToString());
|
||||
MessageBox.Error(ex.ToString(), "程序已崩溃");
|
||||
logger.Fatal(ex.ToString());
|
||||
MessagePopup.Error(ex.ToString(), Properties.Resources.programCrashed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,10 +87,5 @@ namespace SpineViewer
|
||||
config.AddRule(LogLevel.Debug, LogLevel.Fatal, fileTarget);
|
||||
LogManager.Configuration = config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 输出当前内存使用情况
|
||||
/// </summary>
|
||||
public static void LogCurrentMemoryUsage() => Logger.Info("Current memory usage: {:F2} MB", Process.WorkingSet64 / 1024.0 / 1024.0);
|
||||
}
|
||||
}
|
||||
1194
SpineViewer/Properties/Resources.Designer.cs
generated
1194
SpineViewer/Properties/Resources.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
511
SpineViewer/Properties/Resources.en-US.resx
Normal file
511
SpineViewer/Properties/Resources.en-US.resx
Normal file
@@ -0,0 +1,511 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="about" xml:space="preserve">
|
||||
<value>About</value>
|
||||
</data>
|
||||
<data name="animation" xml:space="preserve">
|
||||
<value>Animation</value>
|
||||
</data>
|
||||
<data name="atlasNotExist" xml:space="preserve">
|
||||
<value>Atlas file doesn't exist.</value>
|
||||
</data>
|
||||
<data name="atlasPath" xml:space="preserve">
|
||||
<value>Atlas file path</value>
|
||||
</data>
|
||||
<data name="basicInfo" xml:space="preserve">
|
||||
<value>Basic info</value>
|
||||
</data>
|
||||
<data name="categoryCustom" xml:space="preserve">
|
||||
<value>Custom</value>
|
||||
</data>
|
||||
<data name="categoryExport" xml:space="preserve">
|
||||
<value>[0] Export</value>
|
||||
</data>
|
||||
<data name="categoryFormatParameters" xml:space="preserve">
|
||||
<value>[3] Format parameters</value>
|
||||
</data>
|
||||
<data name="categoryPreview" xml:space="preserve">
|
||||
<value>[1] Preview</value>
|
||||
</data>
|
||||
<data name="countInfoStatusMidfix" xml:space="preserve">
|
||||
<value>item(s) selected,</value>
|
||||
</data>
|
||||
<data name="countInfoStatusPrefix" xml:space="preserve">
|
||||
<value>.</value>
|
||||
</data>
|
||||
<data name="countInfoStatusSuffix" xml:space="preserve">
|
||||
<value>in total.</value>
|
||||
</data>
|
||||
<data name="debug" xml:space="preserve">
|
||||
<value>Debug</value>
|
||||
</data>
|
||||
<data name="descAssociatedSpineListView" xml:space="preserve">
|
||||
<value>Associated SpineListView</value>
|
||||
</data>
|
||||
<data name="descDisplayImageProperties" xml:space="preserve">
|
||||
<value>Property page for displaying image properties</value>
|
||||
</data>
|
||||
<data name="descAvifEncoder" xml:space="preserve">
|
||||
<value>-c:v: Video encoder to use. Hardware acceleration is recommended. Note: libaom-av1 is extremely slow.</value>
|
||||
</data>
|
||||
<data name="descModelAttributes" xml:space="preserve">
|
||||
<value>Model attributes display page.</value>
|
||||
</data>
|
||||
<data name="displayBackgroundColor" xml:space="preserve">
|
||||
<value>Background color</value>
|
||||
</data>
|
||||
<data name="displayCenter" xml:space="preserve">
|
||||
<value>Center point of screen</value>
|
||||
</data>
|
||||
<data name="displayEncoder" xml:space="preserve">
|
||||
<value>Encoder</value>
|
||||
</data>
|
||||
<data name="displayFlipHorizontal" xml:space="preserve">
|
||||
<value>Flip horizontal</value>
|
||||
</data>
|
||||
<data name="displayFlipVertical" xml:space="preserve">
|
||||
<value>Flip vertical</value>
|
||||
</data>
|
||||
<data name="displayMaximumFrameRate" xml:space="preserve">
|
||||
<value>Maximum frame rate</value>
|
||||
</data>
|
||||
<data name="displayRenderSelected" xml:space="preserve">
|
||||
<value>Render selected only</value>
|
||||
</data>
|
||||
<data name="displayResolution" xml:space="preserve">
|
||||
<value>Resolution</value>
|
||||
</data>
|
||||
<data name="displayRotation" xml:space="preserve">
|
||||
<value>Rotation</value>
|
||||
</data>
|
||||
<data name="displayShowAxis" xml:space="preserve">
|
||||
<value>Show axis</value>
|
||||
</data>
|
||||
<data name="displayZoom" xml:space="preserve">
|
||||
<value>Zoom</value>
|
||||
</data>
|
||||
<data name="duration" xml:space="preserve">
|
||||
<value>Duration</value>
|
||||
</data>
|
||||
<data name="errorLoadSkeleton" xml:space="preserve">
|
||||
<value>Failed to load skeleton</value>
|
||||
</data>
|
||||
<data name="fileVersion" xml:space="preserve">
|
||||
<value>File version</value>
|
||||
</data>
|
||||
<data name="flipX" xml:space="preserve">
|
||||
<value>FlipX</value>
|
||||
</data>
|
||||
<data name="flipY" xml:space="preserve">
|
||||
<value>FlipY</value>
|
||||
</data>
|
||||
<data name="formatExceptionParseColor" xml:space="preserve">
|
||||
<value>Unable to parse color, please use #RRGGBBAA, #RRGGBB, #RGBA or #RGB format.</value>
|
||||
</data>
|
||||
<data name="formatExceptionParseColorError" xml:space="preserve">
|
||||
<value>Color format is invalid. Please check the format.</value>
|
||||
</data>
|
||||
<data name="formatExceptionUnknownColor" xml:space="preserve">
|
||||
<value>Color not recognized. Please use a valid color name.</value>
|
||||
</data>
|
||||
<data name="isHidden" xml:space="preserve">
|
||||
<value>Is hidden</value>
|
||||
</data>
|
||||
<data name="itemCountPrefix" xml:space="preserve">
|
||||
<value>.</value>
|
||||
</data>
|
||||
<data name="itemCountSuffix" xml:space="preserve">
|
||||
<value> item(s) selected.</value>
|
||||
</data>
|
||||
<data name="loadAllSkeletonPrefix" xml:space="preserve">
|
||||
<value>A total of </value>
|
||||
</data>
|
||||
<data name="loadAllSkeletonSuffix" xml:space="preserve">
|
||||
<value>skeletons found. Do you want to load them all at once?</value>
|
||||
</data>
|
||||
<data name="maximumTrackLength" xml:space="preserve">
|
||||
<value>Maximum Track Length</value>
|
||||
</data>
|
||||
<data name="msgBoxError" xml:space="preserve">
|
||||
<value>Error</value>
|
||||
</data>
|
||||
<data name="msgBoxInfo" xml:space="preserve">
|
||||
<value>Info</value>
|
||||
</data>
|
||||
<data name="msgBoxQuest" xml:space="preserve">
|
||||
<value>Action Confirmation</value>
|
||||
</data>
|
||||
<data name="msgBoxWarning" xml:space="preserve">
|
||||
<value>Warning</value>
|
||||
</data>
|
||||
<data name="name" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<data name="notifyCopyGithubLink" xml:space="preserve">
|
||||
<value>Link copied to clipboard. Please open it in browser</value>
|
||||
</data>
|
||||
<data name="parameterError" xml:space="preserve">
|
||||
<value>Invalid Parameters</value>
|
||||
</data>
|
||||
<data name="position" xml:space="preserve">
|
||||
<value>Position</value>
|
||||
</data>
|
||||
<data name="previewRenderStopped" xml:space="preserve">
|
||||
<value>Preview Render Stopped</value>
|
||||
</data>
|
||||
<data name="process" xml:space="preserve">
|
||||
<value>Processed </value>
|
||||
</data>
|
||||
<data name="programCrashed" xml:space="preserve">
|
||||
<value>Application has crashed</value>
|
||||
</data>
|
||||
<data name="removeAllItemPrefix" xml:space="preserve">
|
||||
<value>Remove all </value>
|
||||
</data>
|
||||
<data name="removeItemConfirmPrefix" xml:space="preserve">
|
||||
<value>Remove </value>
|
||||
</data>
|
||||
<data name="removeItemConfirmSuffix" xml:space="preserve">
|
||||
<value> item(s)?</value>
|
||||
</data>
|
||||
<data name="render" xml:space="preserve">
|
||||
<value>Render</value>
|
||||
</data>
|
||||
<data name="resourcesPath" xml:space="preserve">
|
||||
<value>Resource Path</value>
|
||||
</data>
|
||||
<data name="restartPrompt" xml:space="preserve">
|
||||
<value>Language set to Simplified Chinese. Restart application now?</value>
|
||||
</data>
|
||||
<data name="restartTitle" xml:space="preserve">
|
||||
<value>Application restart required!</value>
|
||||
</data>
|
||||
<data name="runtimeError" xml:space="preserve">
|
||||
<value>Runtime error</value>
|
||||
</data>
|
||||
<data name="runtimeVersion" xml:space="preserve">
|
||||
<value>Runtime version</value>
|
||||
</data>
|
||||
<data name="scale" xml:space="preserve">
|
||||
<value>Scale</value>
|
||||
</data>
|
||||
<data name="skelNotExist" xml:space="preserve">
|
||||
<value>Skel file doesn't exist.</value>
|
||||
</data>
|
||||
<data name="skelPath" xml:space="preserve">
|
||||
<value>Skel file path</value>
|
||||
</data>
|
||||
<data name="skin" xml:space="preserve">
|
||||
<value>Skin</value>
|
||||
</data>
|
||||
<data name="slot" xml:space="preserve">
|
||||
<value>Slot</value>
|
||||
</data>
|
||||
<data name="transform" xml:space="preserve">
|
||||
<value>Transform</value>
|
||||
</data>
|
||||
<data name="usePremultipliedAlpha" xml:space="preserve">
|
||||
<value>UsePremultipliedAlpha</value>
|
||||
</data>
|
||||
<data name="descCRF" xml:space="preserve">
|
||||
<value>-crf: Accepts values from 0 to 63. Recommended range is 18–28 (default is 23). Lower values result in higher output quality</value>
|
||||
</data>
|
||||
<data name="displayPixelFormat" xml:space="preserve">
|
||||
<value>Pixel format</value>
|
||||
</data>
|
||||
<data name="descPixelFormat" xml:space="preserve">
|
||||
<value>-pix_fmt: Pixel format to use.</value>
|
||||
</data>
|
||||
<data name="displayLoopCount" xml:space="preserve">
|
||||
<value>Loop count</value>
|
||||
</data>
|
||||
<data name="descLoopCount" xml:space="preserve">
|
||||
<value>-loop: Number of loops. 0 for infinite loops. Valid range: [0, 65535].</value>
|
||||
</data>
|
||||
<data name="invalidInputFolder" xml:space="preserve">
|
||||
<value>Invalid output folder</value>
|
||||
</data>
|
||||
<data name="folderNotExistPrefix" xml:space="preserve">
|
||||
<value>Folder </value>
|
||||
</data>
|
||||
<data name="folderNotExistSuffix" xml:space="preserve">
|
||||
<value>doesn't exist.</value>
|
||||
</data>
|
||||
<data name="mustProvideOutputFolder" xml:space="preserve">
|
||||
<value>An output folder must be provided when exporting a single file.</value>
|
||||
</data>
|
||||
<data name="categoryFFmpegParameter" xml:space="preserve">
|
||||
<value>[2] FFmpeg Basic Parameters</value>
|
||||
</data>
|
||||
<data name="displayFileFormat" xml:space="preserve">
|
||||
<value>File format</value>
|
||||
</data>
|
||||
<data name="descFileFormat" xml:space="preserve">
|
||||
<value>-f: Specify the output file format</value>
|
||||
</data>
|
||||
<data name="displayFilenameSuffix" xml:space="preserve">
|
||||
<value>File extension</value>
|
||||
</data>
|
||||
<data name="descFilenameSuffix" xml:space="preserve">
|
||||
<value>File extension</value>
|
||||
</data>
|
||||
<data name="displayOutputFolder" xml:space="preserve">
|
||||
<value>Output folder</value>
|
||||
</data>
|
||||
<data name="descOutputFolder" xml:space="preserve">
|
||||
<value>Leave empty to export to each model's folder.</value>
|
||||
</data>
|
||||
<data name="displayExportSingle" xml:space="preserve">
|
||||
<value>Export single</value>
|
||||
</data>
|
||||
<data name="descExportSingle" xml:space="preserve">
|
||||
<value>Export all models in a single file, or export each model separately.</value>
|
||||
</data>
|
||||
<data name="descResolution" xml:space="preserve">
|
||||
<value>Set pixel size in preview panel.</value>
|
||||
</data>
|
||||
<data name="displayPreviewViewport" xml:space="preserve">
|
||||
<value>Preview viewport</value>
|
||||
</data>
|
||||
<data name="descPreviewViewport" xml:space="preserve">
|
||||
<value>Preview viewport settings. Adjust in the preview panel.</value>
|
||||
</data>
|
||||
<data name="descRenderSelected" xml:space="preserve">
|
||||
<value>Export selected models only. Adjust this in the preview settings panel.</value>
|
||||
</data>
|
||||
<data name="descBackgroundColor" xml:space="preserve">
|
||||
<value>Background color to use, in #RRGGBBAA format.</value>
|
||||
</data>
|
||||
<data name="displayMargin" xml:space="preserve">
|
||||
<value>Margin</value>
|
||||
</data>
|
||||
<data name="descMargin" xml:space="preserve">
|
||||
<value>Outer canvas margin. This will be added to the final export resolution.</value>
|
||||
</data>
|
||||
<data name="displayPadding" xml:space="preserve">
|
||||
<value>Padding</value>
|
||||
</data>
|
||||
<data name="descPadding" xml:space="preserve">
|
||||
<value>Internal canvas padding. The export resolution remains unchanged, but space will be left around the edges.</value>
|
||||
</data>
|
||||
<data name="displayAllowContentOverflow" xml:space="preserve">
|
||||
<value>Allow content overflow</value>
|
||||
</data>
|
||||
<data name="descAllowContentOverflow" xml:space="preserve">
|
||||
<value>When using the preview resolution, allow content to overflow into the edges and padding areas.</value>
|
||||
</data>
|
||||
<data name="displayAutoResolution" xml:space="preserve">
|
||||
<value>Auto resolution</value>
|
||||
</data>
|
||||
<data name="descAutoResolution" xml:space="preserve">
|
||||
<value>Automatically set resolution based on export content. Edge padding and content overflow settings will be ignored.</value>
|
||||
</data>
|
||||
<data name="validFormatRequired" xml:space="preserve">
|
||||
<value>Valid format required.</value>
|
||||
</data>
|
||||
<data name="validExtensionRequired" xml:space="preserve">
|
||||
<value>Valie extension required.</value>
|
||||
</data>
|
||||
<data name="descCustomArgument" xml:space="preserve">
|
||||
<value>Use "ffmpeg -h encoder=<encoder>" to view supported encoder parameters.
|
||||
Use "ffmpeg -h muxer=<file format>" to view supported file format parameters.</value>
|
||||
</data>
|
||||
<data name="displayCustomArgument" xml:space="preserve">
|
||||
<value>Custom arguments</value>
|
||||
</data>
|
||||
<data name="categorySingleFrame" xml:space="preserve">
|
||||
<value>[1] Single Frame</value>
|
||||
</data>
|
||||
<data name="displayImageFormat" xml:space="preserve">
|
||||
<value>Image format</value>
|
||||
</data>
|
||||
<data name="descFileNameExtension" xml:space="preserve">
|
||||
<value>Filename extension matching the image format.</value>
|
||||
</data>
|
||||
<data name="descDPI" xml:space="preserve">
|
||||
<value>Pixels per inch (PPI) for the exported image, used to adjust the physical size of the image.</value>
|
||||
</data>
|
||||
<data name="categoryFrameSequenceParameters" xml:space="preserve">
|
||||
<value>[2] Frame Sequence Parameters</value>
|
||||
</data>
|
||||
<data name="descFrameFileExtension" xml:space="preserve">
|
||||
<value>Frame file extension, which also defines the image format of each frame.</value>
|
||||
</data>
|
||||
<data name="displayMaxColor" xml:space="preserve">
|
||||
<value>Max colors in palette</value>
|
||||
</data>
|
||||
<data name="descMaxColor" xml:space="preserve">
|
||||
<value>Max colors in palette. Higher value = better color retention.</value>
|
||||
</data>
|
||||
<data name="displayAlphaThreshold" xml:space="preserve">
|
||||
<value>Alpha threshold</value>
|
||||
</data>
|
||||
<data name="descAlphaThreshold" xml:space="preserve">
|
||||
<value>Pixels below this value will be considered transparent.</value>
|
||||
</data>
|
||||
<data name="displayPreset" xml:space="preserve">
|
||||
<value>Preset</value>
|
||||
</data>
|
||||
<data name="descPreset" xml:space="preserve">
|
||||
<value>-profile: Preset configuration</value>
|
||||
</data>
|
||||
<data name="negativeDuration" xml:space="preserve">
|
||||
<value>Export duration cannot be negative when exporting a single file.</value>
|
||||
</data>
|
||||
<data name="frame" xml:space="preserve">
|
||||
<value>frame(s)</value>
|
||||
</data>
|
||||
<data name="categoryVideoParameters" xml:space="preserve">
|
||||
<value>[1] Video Parameters</value>
|
||||
</data>
|
||||
<data name="descDuration" xml:space="preserve">
|
||||
<value>Check animation duration in the model list. If less than 0, each model uses its longest track when exporting individually.</value>
|
||||
</data>
|
||||
<data name="displayFPS" xml:space="preserve">
|
||||
<value>FPS</value>
|
||||
</data>
|
||||
<data name="descFPS" xml:space="preserve">
|
||||
<value>Frames Per Second (FPS)</value>
|
||||
</data>
|
||||
<data name="displayKeepLastFrame" xml:space="preserve">
|
||||
<value>Keep last frame</value>
|
||||
</data>
|
||||
<data name="descKeepLastFrame" xml:space="preserve">
|
||||
<value>Keeping the last frame smooths the animation, but may add one extra frame.</value>
|
||||
</data>
|
||||
<data name="displayLoseless" xml:space="preserve">
|
||||
<value>Loseless</value>
|
||||
</data>
|
||||
<data name="descLoseless" xml:space="preserve">
|
||||
<value>-lossless: 0 for lossy, 1 for lossless.</value>
|
||||
</data>
|
||||
<data name="displayQuality" xml:space="preserve">
|
||||
<value>Quality</value>
|
||||
</data>
|
||||
<data name="descQuality" xml:space="preserve">
|
||||
<value>-quality: Range 0-100, default is 75.</value>
|
||||
</data>
|
||||
<data name="failLoadingFragmentShader" xml:space="preserve">
|
||||
<value>Fragment shader failed to load, pre-multiplied alpha channel property disabled.</value>
|
||||
</data>
|
||||
<data name="isUpdatingAndManuallyExportFrame" xml:space="preserve">
|
||||
<value>The screen is still updating. It’s recommended to manually pause and export a fixed frame. Do you want to continue?</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,4 +117,394 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="about" xml:space="preserve">
|
||||
<value>关于 </value>
|
||||
</data>
|
||||
<data name="animation" xml:space="preserve">
|
||||
<value>动画</value>
|
||||
</data>
|
||||
<data name="atlasNotExist" xml:space="preserve">
|
||||
<value>atlas文件不存在</value>
|
||||
</data>
|
||||
<data name="atlasPath" xml:space="preserve">
|
||||
<value>atlas文件路径</value>
|
||||
</data>
|
||||
<data name="basicInfo" xml:space="preserve">
|
||||
<value>基本信息</value>
|
||||
</data>
|
||||
<data name="categoryCustom" xml:space="preserve">
|
||||
<value>自定义</value>
|
||||
</data>
|
||||
<data name="categoryExport" xml:space="preserve">
|
||||
<value>[0] 导出</value>
|
||||
</data>
|
||||
<data name="categoryFormatParameters" xml:space="preserve">
|
||||
<value>[3] 格式参数</value>
|
||||
</data>
|
||||
<data name="categoryPreview" xml:space="preserve">
|
||||
<value>[1] 预览</value>
|
||||
</data>
|
||||
<data name="countInfoStatusMidfix" xml:space="preserve">
|
||||
<value> 项,共 </value>
|
||||
</data>
|
||||
<data name="countInfoStatusPrefix" xml:space="preserve">
|
||||
<value>已选择 </value>
|
||||
</data>
|
||||
<data name="countInfoStatusSuffix" xml:space="preserve">
|
||||
<value> 项</value>
|
||||
</data>
|
||||
<data name="debug" xml:space="preserve">
|
||||
<value>调试</value>
|
||||
</data>
|
||||
<data name="descAssociatedSpineListView" xml:space="preserve">
|
||||
<value>相关联的 SpineListView</value>
|
||||
</data>
|
||||
<data name="descDisplayImageProperties" xml:space="preserve">
|
||||
<value>用于显示画面属性的属性页</value>
|
||||
</data>
|
||||
<data name="descAvifEncoder" xml:space="preserve">
|
||||
<value>-c:v, 要使用的编码器\n建议使用硬件加速, libaom-av1 速度非常非常非常慢</value>
|
||||
</data>
|
||||
<data name="descModelAttributes" xml:space="preserve">
|
||||
<value>用于显示模型属性的组合属性页</value>
|
||||
</data>
|
||||
<data name="displayBackgroundColor" xml:space="preserve">
|
||||
<value>背景颜色</value>
|
||||
</data>
|
||||
<data name="displayCenter" xml:space="preserve">
|
||||
<value>画面中心点</value>
|
||||
</data>
|
||||
<data name="displayEncoder" xml:space="preserve">
|
||||
<value>编码器</value>
|
||||
</data>
|
||||
<data name="displayFlipHorizontal" xml:space="preserve">
|
||||
<value>水平翻转</value>
|
||||
</data>
|
||||
<data name="displayFlipVertical" xml:space="preserve">
|
||||
<value>垂直翻转</value>
|
||||
</data>
|
||||
<data name="displayMaximumFrameRate" xml:space="preserve">
|
||||
<value>最大帧率</value>
|
||||
</data>
|
||||
<data name="displayRenderSelected" xml:space="preserve">
|
||||
<value>仅渲染选中</value>
|
||||
</data>
|
||||
<data name="displayResolution" xml:space="preserve">
|
||||
<value>分辨率</value>
|
||||
</data>
|
||||
<data name="displayRotation" xml:space="preserve">
|
||||
<value>旋转</value>
|
||||
</data>
|
||||
<data name="displayShowAxis" xml:space="preserve">
|
||||
<value>显示坐标轴</value>
|
||||
</data>
|
||||
<data name="displayZoom" xml:space="preserve">
|
||||
<value>缩放</value>
|
||||
</data>
|
||||
<data name="duration" xml:space="preserve">
|
||||
<value>时长</value>
|
||||
</data>
|
||||
<data name="errorLoadSkeleton" xml:space="preserve">
|
||||
<value>骨骼加载失败</value>
|
||||
</data>
|
||||
<data name="fileVersion" xml:space="preserve">
|
||||
<value>文件版本</value>
|
||||
</data>
|
||||
<data name="flipX" xml:space="preserve">
|
||||
<value>水平翻转</value>
|
||||
</data>
|
||||
<data name="flipY" xml:space="preserve">
|
||||
<value>垂直翻转</value>
|
||||
</data>
|
||||
<data name="formatExceptionParseColor" xml:space="preserve">
|
||||
<value>无法解析颜色,请使用 #RRGGBBAA、#RRGGBB、#RGBA 或 #RGB 格式</value>
|
||||
</data>
|
||||
<data name="formatExceptionParseColorError" xml:space="preserve">
|
||||
<value>无法解析颜色,请检查格式</value>
|
||||
</data>
|
||||
<data name="formatExceptionUnknownColor" xml:space="preserve">
|
||||
<value>无法解析颜色,请使用已知的颜色名称</value>
|
||||
</data>
|
||||
<data name="isHidden" xml:space="preserve">
|
||||
<value>是否隐藏</value>
|
||||
</data>
|
||||
<data name="itemCountPrefix" xml:space="preserve">
|
||||
<value>已选择 </value>
|
||||
</data>
|
||||
<data name="itemCountSuffix" xml:space="preserve">
|
||||
<value> 个文件</value>
|
||||
</data>
|
||||
<data name="loadAllSkeletonPrefix" xml:space="preserve">
|
||||
<value>共发现 </value>
|
||||
</data>
|
||||
<data name="loadAllSkeletonSuffix" xml:space="preserve">
|
||||
<value> 个可加载骨骼,数量较多,是否一次性全部加载?</value>
|
||||
</data>
|
||||
<data name="maximumTrackLength" xml:space="preserve">
|
||||
<value>全轨道最大时长</value>
|
||||
</data>
|
||||
<data name="msgBoxError" xml:space="preserve">
|
||||
<value>错误信息</value>
|
||||
</data>
|
||||
<data name="msgBoxInfo" xml:space="preserve">
|
||||
<value>提示信息</value>
|
||||
</data>
|
||||
<data name="msgBoxQuest" xml:space="preserve">
|
||||
<value>操作确认</value>
|
||||
</data>
|
||||
<data name="msgBoxWarning" xml:space="preserve">
|
||||
<value>警告信息</value>
|
||||
</data>
|
||||
<data name="name" xml:space="preserve">
|
||||
<value>名称</value>
|
||||
</data>
|
||||
<data name="notifyCopyGithubLink" xml:space="preserve">
|
||||
<value>链接已复制到剪贴板,请前往浏览器进行访问</value>
|
||||
</data>
|
||||
<data name="parameterError" xml:space="preserve">
|
||||
<value>参数错误</value>
|
||||
</data>
|
||||
<data name="position" xml:space="preserve">
|
||||
<value>位置</value>
|
||||
</data>
|
||||
<data name="previewRenderStopped" xml:space="preserve">
|
||||
<value>预览画面已停止渲染</value>
|
||||
</data>
|
||||
<data name="process" xml:space="preserve">
|
||||
<value>已处理 </value>
|
||||
</data>
|
||||
<data name="programCrashed" xml:space="preserve">
|
||||
<value>程序已崩溃</value>
|
||||
</data>
|
||||
<data name="removeAllItemPrefix" xml:space="preserve">
|
||||
<value>确认移除所有 </value>
|
||||
</data>
|
||||
<data name="removeItemConfirmPrefix" xml:space="preserve">
|
||||
<value>确定移除所选 </value>
|
||||
</data>
|
||||
<data name="removeItemConfirmSuffix" xml:space="preserve">
|
||||
<value> 项吗?</value>
|
||||
</data>
|
||||
<data name="render" xml:space="preserve">
|
||||
<value>渲染</value>
|
||||
</data>
|
||||
<data name="resourcesPath" xml:space="preserve">
|
||||
<value>资源目录</value>
|
||||
</data>
|
||||
<data name="restartPrompt" xml:space="preserve">
|
||||
<value>语言已设为英语。立即重启应用程序吗?</value>
|
||||
</data>
|
||||
<data name="restartTitle" xml:space="preserve">
|
||||
<value>需要重新启动应用程序!</value>
|
||||
</data>
|
||||
<data name="runtimeError" xml:space="preserve">
|
||||
<value>执行出错</value>
|
||||
</data>
|
||||
<data name="runtimeVersion" xml:space="preserve">
|
||||
<value>运行时版本</value>
|
||||
</data>
|
||||
<data name="scale" xml:space="preserve">
|
||||
<value>缩放比例</value>
|
||||
</data>
|
||||
<data name="skelNotExist" xml:space="preserve">
|
||||
<value>skel文件不存在</value>
|
||||
</data>
|
||||
<data name="skelPath" xml:space="preserve">
|
||||
<value>skel文件路径</value>
|
||||
</data>
|
||||
<data name="skin" xml:space="preserve">
|
||||
<value>皮肤</value>
|
||||
</data>
|
||||
<data name="slot" xml:space="preserve">
|
||||
<value>插槽</value>
|
||||
</data>
|
||||
<data name="transform" xml:space="preserve">
|
||||
<value>变换</value>
|
||||
</data>
|
||||
<data name="usePremultipliedAlpha" xml:space="preserve">
|
||||
<value>预乘Alpha通道</value>
|
||||
</data>
|
||||
<data name="descCRF" xml:space="preserve">
|
||||
<value>-crf, 取值范围 0-63, 建议范围 18-28, 默认取值 23, 数值越小则输出质量越高</value>
|
||||
</data>
|
||||
<data name="displayPixelFormat" xml:space="preserve">
|
||||
<value>像素格式</value>
|
||||
</data>
|
||||
<data name="descPixelFormat" xml:space="preserve">
|
||||
<value>-pix_fmt, 要使用的像素格式</value>
|
||||
</data>
|
||||
<data name="displayLoopCount" xml:space="preserve">
|
||||
<value>循环次数</value>
|
||||
</data>
|
||||
<data name="descLoopCount" xml:space="preserve">
|
||||
<value>-loop, 循环次数, 0 无限循环, 取值范围 [0, 65535]</value>
|
||||
</data>
|
||||
<data name="invalidInputFolder" xml:space="preserve">
|
||||
<value>输出文件夹无效</value>
|
||||
</data>
|
||||
<data name="folderNotExistPrefix" xml:space="preserve">
|
||||
<value>文件夹 </value>
|
||||
</data>
|
||||
<data name="folderNotExistSuffix" xml:space="preserve">
|
||||
<value>不存在</value>
|
||||
</data>
|
||||
<data name="mustProvideOutputFolder" xml:space="preserve">
|
||||
<value>导出单个时必须提供输出文件夹</value>
|
||||
</data>
|
||||
<data name="categoryFFmpegParameter" xml:space="preserve">
|
||||
<value>[2] FFmpeg 基本参数</value>
|
||||
</data>
|
||||
<data name="displayFileFormat" xml:space="preserve">
|
||||
<value>文件格式</value>
|
||||
</data>
|
||||
<data name="descFileFormat" xml:space="preserve">
|
||||
<value>-f, 文件格式</value>
|
||||
</data>
|
||||
<data name="displayFilenameSuffix" xml:space="preserve">
|
||||
<value>文件名后缀</value>
|
||||
</data>
|
||||
<data name="descFilenameSuffix" xml:space="preserve">
|
||||
<value>文件名后缀</value>
|
||||
</data>
|
||||
<data name="displayOutputFolder" xml:space="preserve">
|
||||
<value>输出文件夹</value>
|
||||
</data>
|
||||
<data name="descOutputFolder" xml:space="preserve">
|
||||
<value>逐个导出时可以留空,将逐个导出到模型自身所在目录</value>
|
||||
</data>
|
||||
<data name="displayExportSingle" xml:space="preserve">
|
||||
<value>导出单个</value>
|
||||
</data>
|
||||
<data name="descExportSingle" xml:space="preserve">
|
||||
<value>是否将模型在同一个画面上导出单个文件,否则逐个导出模型</value>
|
||||
</data>
|
||||
<data name="descResolution" xml:space="preserve">
|
||||
<value>是否将模型在同一个画面上导出单个文件,否则逐个导出模型</value>
|
||||
</data>
|
||||
<data name="displayPreviewViewport" xml:space="preserve">
|
||||
<value>预览画面视区</value>
|
||||
</data>
|
||||
<data name="descPreviewViewport" xml:space="preserve">
|
||||
<value>预览画面的视区参数,请在预览画面参数面板进行调整</value>
|
||||
</data>
|
||||
<data name="descRenderSelected" xml:space="preserve">
|
||||
<value>是否仅导出选中的模型,请在预览画面参数面板进行调整</value>
|
||||
</data>
|
||||
<data name="descBackgroundColor" xml:space="preserve">
|
||||
<value>要使用的背景色, 格式为 #RRGGBBAA</value>
|
||||
</data>
|
||||
<data name="displayMargin" xml:space="preserve">
|
||||
<value>四周边缘距离</value>
|
||||
</data>
|
||||
<data name="descMargin" xml:space="preserve">
|
||||
<value>画布外部的边缘距离 (Margin), 最终导出的分辨率需要加上这个边距</value>
|
||||
</data>
|
||||
<data name="displayPadding" xml:space="preserve">
|
||||
<value>四周填充距离</value>
|
||||
</data>
|
||||
<data name="descPadding" xml:space="preserve">
|
||||
<value>画布内部的填充距离 (Padding), 导出的分辨率大小不会发生变化, 但是会留有四周空间</value>
|
||||
</data>
|
||||
<data name="displayAllowContentOverflow" xml:space="preserve">
|
||||
<value>允许内容溢出</value>
|
||||
</data>
|
||||
<data name="descAllowContentOverflow" xml:space="preserve">
|
||||
<value>使用预览画面分辨率的情况下, 允许内容溢出到边缘和填充区域</value>
|
||||
</data>
|
||||
<data name="displayAutoResolution" xml:space="preserve">
|
||||
<value>自动分辨率</value>
|
||||
</data>
|
||||
<data name="descAutoResolution" xml:space="preserve">
|
||||
<value>根据导出内容自动设置分辨率, 四周填充距离和内容溢出参数将会被忽略</value>
|
||||
</data>
|
||||
<data name="validFormatRequired" xml:space="preserve">
|
||||
<value>需要提供有效的格式</value>
|
||||
</data>
|
||||
<data name="validExtensionRequired" xml:space="preserve">
|
||||
<value>需要提供有效的文件名后缀</value>
|
||||
</data>
|
||||
<data name="descCustomArgument" xml:space="preserve">
|
||||
<value>使用 \"ffmpeg -h encoder=<编码器>\" 查看编码器支持的参数\n使用 \"ffmpeg -h muxer=<文件格式>\" 查看文件格式支持的参数</value>
|
||||
</data>
|
||||
<data name="displayCustomArgument" xml:space="preserve">
|
||||
<value>自定义参数</value>
|
||||
</data>
|
||||
<data name="categorySingleFrame" xml:space="preserve">
|
||||
<value>[1] 单帧画面</value>
|
||||
</data>
|
||||
<data name="displayImageFormat" xml:space="preserve">
|
||||
<value>图像格式</value>
|
||||
</data>
|
||||
<data name="descFileNameExtension" xml:space="preserve">
|
||||
<value>与图像格式匹配的文件名后缀</value>
|
||||
</data>
|
||||
<data name="descDPI" xml:space="preserve">
|
||||
<value>导出图像的每英寸像素数,用于调整图像的物理尺寸</value>
|
||||
</data>
|
||||
<data name="categoryFrameSequenceParameters" xml:space="preserve">
|
||||
<value>[2] 帧序列参数</value>
|
||||
</data>
|
||||
<data name="descFrameFileExtension" xml:space="preserve">
|
||||
<value>帧文件的后缀,同时决定帧图像格式</value>
|
||||
</data>
|
||||
<data name="displayMaxColor" xml:space="preserve">
|
||||
<value>调色板最大颜色数量</value>
|
||||
</data>
|
||||
<data name="descMaxColor" xml:space="preserve">
|
||||
<value>设置调色板使用的最大颜色数量, 越多则色彩保留程度越高</value>
|
||||
</data>
|
||||
<data name="displayAlphaThreshold" xml:space="preserve">
|
||||
<value>透明度阈值</value>
|
||||
</data>
|
||||
<data name="descAlphaThreshold" xml:space="preserve">
|
||||
<value>小于该值的像素点会被认为是透明像素</value>
|
||||
</data>
|
||||
<data name="displayPreset" xml:space="preserve">
|
||||
<value>预设</value>
|
||||
</data>
|
||||
<data name="descPreset" xml:space="preserve">
|
||||
<value>-profile, 预设配置</value>
|
||||
</data>
|
||||
<data name="negativeDuration" xml:space="preserve">
|
||||
<value>导出单个时导出时长不能为负数</value>
|
||||
</data>
|
||||
<data name="frame" xml:space="preserve">
|
||||
<value>帧</value>
|
||||
</data>
|
||||
<data name="categoryVideoParameters" xml:space="preserve">
|
||||
<value>[1] 视频参数</value>
|
||||
</data>
|
||||
<data name="descDuration" xml:space="preserve">
|
||||
<value>可以从模型列表查看动画时长, 如果小于 0, 则在逐个导出时每个模型使用各自的所有轨道动画时长最大值</value>
|
||||
</data>
|
||||
<data name="displayFPS" xml:space="preserve">
|
||||
<value>帧率</value>
|
||||
</data>
|
||||
<data name="descFPS" xml:space="preserve">
|
||||
<value>每秒画面数</value>
|
||||
</data>
|
||||
<data name="displayKeepLastFrame" xml:space="preserve">
|
||||
<value>保留最后一帧</value>
|
||||
</data>
|
||||
<data name="descKeepLastFrame" xml:space="preserve">
|
||||
<value>当设置保留最后一帧时, 动图会更为连贯, 但是帧数可能比预期帧数多 1</value>
|
||||
</data>
|
||||
<data name="displayLoseless" xml:space="preserve">
|
||||
<value>无损</value>
|
||||
</data>
|
||||
<data name="descLoseless" xml:space="preserve">
|
||||
<value>-lossless, 0 表示有损, 1 表示无损</value>
|
||||
</data>
|
||||
<data name="displayQuality" xml:space="preserve">
|
||||
<value>质量</value>
|
||||
</data>
|
||||
<data name="descQuality" xml:space="preserve">
|
||||
<value>-quality, 取值范围 0-100, 默认值 75</value>
|
||||
</data>
|
||||
<data name="failLoadingFragmentShader" xml:space="preserve">
|
||||
<value>Fragment shader 加载失败,预乘Alpha通道属性失效</value>
|
||||
</data>
|
||||
<data name="isUpdatingAndManuallyExportFrame" xml:space="preserve">
|
||||
<value>画面仍在更新,建议手动暂停画面后导出固定的一帧,是否继续?</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1,64 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpineViewer.Spine
|
||||
{
|
||||
/// <summary>
|
||||
/// SFML 混合模式
|
||||
/// </summary>
|
||||
public static class BlendModeSFML
|
||||
{
|
||||
/// <summary>
|
||||
/// Alpha Blend
|
||||
/// <code>
|
||||
/// res.c = src.c * src.a + dst.c * (1 - src.a)
|
||||
/// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode Normal = SFML.Graphics.BlendMode.Alpha;
|
||||
|
||||
/// <summary>
|
||||
/// Additive Blend
|
||||
/// <code>
|
||||
/// res.c = src.c * src.a + dst.c * 1
|
||||
/// res.a = src.a * 1 + dst.a * 1
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode Additive = SFML.Graphics.BlendMode.Add;
|
||||
|
||||
/// <summary>
|
||||
/// Multiply Blend (PremultipliedAlpha Only)
|
||||
/// <code>
|
||||
/// res.c = src.c * dst.c + dst.c * (1 - src.a)
|
||||
/// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode Multiply = new(
|
||||
SFML.Graphics.BlendMode.Factor.DstColor,
|
||||
SFML.Graphics.BlendMode.Factor.OneMinusSrcAlpha,
|
||||
SFML.Graphics.BlendMode.Equation.Add,
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Factor.OneMinusSrcAlpha,
|
||||
SFML.Graphics.BlendMode.Equation.Add
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Screen Blend (PremultipliedAlpha Only)
|
||||
/// <code>
|
||||
/// res.c = src.c * 1 + dst.c * (1 - src.c) = 1 - [(1 - src.c)(1 - dst.c)]
|
||||
/// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode Screen = new(
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Factor.OneMinusSrcColor,
|
||||
SFML.Graphics.BlendMode.Equation.Add,
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Factor.OneMinusSrcAlpha,
|
||||
SFML.Graphics.BlendMode.Equation.Add
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,396 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime21;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
[SpineImplementation(Version.V21)]
|
||||
internal class Spine21 : SpineViewer.Spine.Spine
|
||||
{
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private class TextureLoader : SpineRuntime21.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
page.width = (int)texture.Size.X;
|
||||
page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
private static TextureLoader textureLoader = new();
|
||||
|
||||
private Atlas atlas;
|
||||
private SkeletonBinary? skeletonBinary;
|
||||
private SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
// 2.1.x 不支持剪裁
|
||||
//private SkeletonClipping clipping = new();
|
||||
|
||||
public Spine21(string skelPath, string? atlasPath = null) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
foreach (var anime in skeletonData.Animations)
|
||||
animationNames.Add(anime.Name);
|
||||
CurrentAnimation = DefaultAnimationName;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
public override float Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skeletonBinary is not null)
|
||||
return skeletonBinary.Scale;
|
||||
else if (skeletonJson is not null)
|
||||
return skeletonJson.Scale;
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
set
|
||||
{
|
||||
// 保存状态
|
||||
var position = Position;
|
||||
var flipX = FlipX;
|
||||
var flipY = FlipY;
|
||||
var savedTrack0 = animationState.GetCurrent(0);
|
||||
|
||||
var val = Math.Max(value, SCALE_MIN);
|
||||
if (skeletonBinary is not null)
|
||||
{
|
||||
skeletonBinary.Scale = val;
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
else if (skeletonJson is not null)
|
||||
{
|
||||
skeletonJson.Scale = val;
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
|
||||
// reload skel-dependent data
|
||||
animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix };
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
// 恢复状态
|
||||
Position = position;
|
||||
FlipX = flipX;
|
||||
FlipY = flipY;
|
||||
|
||||
// 恢复原本 Track0 上所有动画
|
||||
if (savedTrack0 is not null)
|
||||
{
|
||||
var entry = animationState.SetAnimation(0, savedTrack0.Animation.Name, true);
|
||||
entry.Time = savedTrack0.Time;
|
||||
// 2.1.x 没有提供 Next 访问器,故放弃还原后续动画,问题不大,因为预览画面目前不需要连续播放不同动画,只需要循环同一个动画
|
||||
//var savedEntry = savedTrack0.Next;
|
||||
//while (savedEntry is not null)
|
||||
//{
|
||||
// entry = animationState.AddAnimation(0, savedEntry.Animation.Name, true, 0);
|
||||
// entry.Time = savedEntry.TrackTime;
|
||||
// savedEntry = savedEntry.Next;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override PointF Position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipX
|
||||
{
|
||||
get => skeleton.FlipX;
|
||||
set => skeleton.FlipX = value;
|
||||
}
|
||||
|
||||
public override bool FlipY
|
||||
{
|
||||
get => skeleton.FlipY;
|
||||
set => skeleton.FlipY = value;
|
||||
}
|
||||
|
||||
public override string CurrentAnimation
|
||||
{
|
||||
get => animationState.GetCurrent(0)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
set
|
||||
{
|
||||
if (value == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(0, EmptyAnimation, false);
|
||||
else if (animationNames.Contains(value))
|
||||
animationState.SetAnimation(0, value, true);
|
||||
Update(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
float[] temp = new float[8];
|
||||
var drawOrderItems = skeleton.DrawOrder;
|
||||
float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
|
||||
for (int i = 0, n = skeleton.DrawOrder.Count; i < n; i++)
|
||||
{
|
||||
Slot slot = drawOrderItems[i];
|
||||
int verticesLength = 0;
|
||||
float[] vertices = null;
|
||||
Attachment attachment = slot.Attachment;
|
||||
var regionAttachment = attachment as RegionAttachment;
|
||||
if (regionAttachment != null)
|
||||
{
|
||||
verticesLength = 8;
|
||||
vertices = temp;
|
||||
if (vertices.Length < 8) vertices = temp = new float[8];
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
var meshAttachment = attachment as MeshAttachment;
|
||||
if (meshAttachment != null)
|
||||
{
|
||||
MeshAttachment mesh = meshAttachment;
|
||||
verticesLength = mesh.Vertices.Length;
|
||||
vertices = temp;
|
||||
if (vertices.Length < verticesLength) vertices = temp = new float[verticesLength];
|
||||
mesh.ComputeWorldVertices(slot, temp);
|
||||
}
|
||||
}
|
||||
|
||||
if (vertices != null)
|
||||
{
|
||||
for (int ii = 0; ii < verticesLength; ii += 2)
|
||||
{
|
||||
float vx = vertices[ii], vy = vertices[ii + 1];
|
||||
minX = Math.Min(minX, vx);
|
||||
minY = Math.Min(minY, vy);
|
||||
maxX = Math.Max(maxX, vx);
|
||||
maxY = Math.Max(maxY, vy);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new RectangleF(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
skeleton.Update(delta);
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
//private SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
//{
|
||||
// return spineBlendMode switch
|
||||
// {
|
||||
// BlendMode.Normal => BlendMode.Normal,
|
||||
// BlendMode.Additive => BlendMode.Additive,
|
||||
// BlendMode.Multiply => BlendMode.Multiply,
|
||||
// BlendMode.Screen => BlendMode.Screen,
|
||||
// _ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
// };
|
||||
//}
|
||||
|
||||
public override void Draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices);
|
||||
worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (meshAttachment.Vertices.Length > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.Vertices.Length / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
// 2.1.x 不支持剪裁
|
||||
//else if (attachment is ClippingAttachment clippingAttachment)
|
||||
//{
|
||||
// clipping.ClipStart(slot, clippingAttachment);
|
||||
// continue;
|
||||
//}
|
||||
else
|
||||
{
|
||||
//clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 似乎 2.1.x 也没有 BlendMode
|
||||
SFML.Graphics.BlendMode blendMode = slot.Data.AdditiveBlending ? BlendModeSFML.Additive : BlendModeSFML.Normal;
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
vertexArray.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
//if (clipping.IsClipping)
|
||||
//{
|
||||
// // 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
// clipping.ClipTriangles(worldVertices, worldVerticesCount * 2, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
// worldVertices = clipping.ClippedVertices.Items;
|
||||
// worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
// worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
// worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
// uvs = clipping.ClippedUVs.Items;
|
||||
//}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
vertexArray.Append(vertex);
|
||||
}
|
||||
|
||||
//clipping.ClipEnd(slot);
|
||||
}
|
||||
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
//clipping.ClipEnd();
|
||||
|
||||
// 包围盒
|
||||
if (IsDebug && IsSelected && DebugBounds)
|
||||
{
|
||||
var bounds = Bounds;
|
||||
boundsVertices[0] = boundsVertices[4] = new(new(bounds.Left, bounds.Top), BoundsColor);
|
||||
boundsVertices[1] = new(new(bounds.Right, bounds.Top), BoundsColor);
|
||||
boundsVertices[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor);
|
||||
boundsVertices[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor);
|
||||
target.Draw(boundsVertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime36;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
[SpineImplementation(Version.V36)]
|
||||
internal class Spine36 : SpineViewer.Spine.Spine
|
||||
{
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private class TextureLoader : SpineRuntime36.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
page.width = (int)texture.Size.X;
|
||||
page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
private static TextureLoader textureLoader = new();
|
||||
|
||||
private Atlas atlas;
|
||||
private SkeletonBinary? skeletonBinary;
|
||||
private SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
private SkeletonClipping clipping = new();
|
||||
|
||||
public Spine36(string skelPath, string? atlasPath = null) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
foreach (var anime in skeletonData.Animations)
|
||||
animationNames.Add(anime.Name);
|
||||
CurrentAnimation = DefaultAnimationName;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
public override float Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skeletonBinary is not null)
|
||||
return skeletonBinary.Scale;
|
||||
else if (skeletonJson is not null)
|
||||
return skeletonJson.Scale;
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
set
|
||||
{
|
||||
// 保存状态
|
||||
var position = Position;
|
||||
var flipX = FlipX;
|
||||
var flipY = FlipY;
|
||||
var savedTrack0 = animationState.GetCurrent(0);
|
||||
|
||||
var val = Math.Max(value, SCALE_MIN);
|
||||
if (skeletonBinary is not null)
|
||||
{
|
||||
skeletonBinary.Scale = val;
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
else if (skeletonJson is not null)
|
||||
{
|
||||
skeletonJson.Scale = val;
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
|
||||
// reload skel-dependent data
|
||||
animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix };
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
// 恢复状态
|
||||
Position = position;
|
||||
FlipX = flipX;
|
||||
FlipY = flipY;
|
||||
|
||||
// 恢复原本 Track0 上所有动画
|
||||
if (savedTrack0 is not null)
|
||||
{
|
||||
var entry = animationState.SetAnimation(0, savedTrack0.Animation.Name, true);
|
||||
entry.TrackTime = savedTrack0.TrackTime;
|
||||
var savedEntry = savedTrack0.Next;
|
||||
while (savedEntry is not null)
|
||||
{
|
||||
entry = animationState.AddAnimation(0, savedEntry.Animation.Name, true, 0);
|
||||
entry.TrackTime = savedEntry.TrackTime;
|
||||
savedEntry = savedEntry.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override PointF Position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipX
|
||||
{
|
||||
get => skeleton.FlipX;
|
||||
set => skeleton.FlipX = value;
|
||||
}
|
||||
|
||||
public override bool FlipY
|
||||
{
|
||||
get => skeleton.FlipY;
|
||||
set => skeleton.FlipY = value;
|
||||
}
|
||||
|
||||
public override string CurrentAnimation
|
||||
{
|
||||
get => animationState.GetCurrent(0)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
set
|
||||
{
|
||||
if (value == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(0, EmptyAnimation, false);
|
||||
else if (animationNames.Contains(value))
|
||||
animationState.SetAnimation(0, value, true);
|
||||
Update(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
float[] _ = [];
|
||||
skeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
return new RectangleF(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
skeleton.Update(delta);
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
private SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
|
||||
public override void Draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices, 0);
|
||||
worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (meshAttachment.WorldVerticesLength > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.WorldVerticesLength / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is ClippingAttachment clippingAttachment)
|
||||
{
|
||||
clipping.ClipStart(slot, clippingAttachment);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
SFML.Graphics.BlendMode blendMode = GetSFMLBlendMode(slot.Data.BlendMode);
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
vertexArray.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
if (clipping.IsClipping)
|
||||
{
|
||||
// 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
clipping.ClipTriangles(worldVertices, worldVerticesCount * 2, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
worldVertices = clipping.ClippedVertices.Items;
|
||||
worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
uvs = clipping.ClippedUVs.Items;
|
||||
}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
vertexArray.Append(vertex);
|
||||
}
|
||||
|
||||
clipping.ClipEnd(slot);
|
||||
}
|
||||
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
clipping.ClipEnd();
|
||||
|
||||
// 包围盒
|
||||
if (IsDebug && IsSelected && DebugBounds)
|
||||
{
|
||||
var bounds = Bounds;
|
||||
boundsVertices[0] = boundsVertices[4] = new(new(bounds.Left, bounds.Top), BoundsColor);
|
||||
boundsVertices[1] = new(new(bounds.Right, bounds.Top), BoundsColor);
|
||||
boundsVertices[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor);
|
||||
boundsVertices[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor);
|
||||
target.Draw(boundsVertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,360 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime37;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
[SpineImplementation(Version.V37)]
|
||||
internal class Spine37 : SpineViewer.Spine.Spine
|
||||
{
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private class TextureLoader : SpineRuntime37.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
page.width = (int)texture.Size.X;
|
||||
page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static TextureLoader textureLoader = new();
|
||||
|
||||
private Atlas atlas;
|
||||
private SkeletonBinary? skeletonBinary;
|
||||
private SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
private SkeletonClipping clipping = new();
|
||||
|
||||
public Spine37(string skelPath, string? atlasPath = null) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
foreach (var anime in skeletonData.Animations)
|
||||
animationNames.Add(anime.Name);
|
||||
|
||||
CurrentAnimation = DefaultAnimationName;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
public override float Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skeletonBinary is not null)
|
||||
return skeletonBinary.Scale;
|
||||
else if (skeletonJson is not null)
|
||||
return skeletonJson.Scale;
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
set
|
||||
{
|
||||
// 保存状态
|
||||
var position = Position;
|
||||
var flipX = FlipX;
|
||||
var flipY = FlipY;
|
||||
var savedTrack0 = animationState.GetCurrent(0);
|
||||
|
||||
var val = Math.Max(value, SCALE_MIN);
|
||||
if (skeletonBinary is not null)
|
||||
{
|
||||
skeletonBinary.Scale = val;
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
else if (skeletonJson is not null)
|
||||
{
|
||||
skeletonJson.Scale = val;
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
|
||||
// reload skel-dependent data
|
||||
animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix };
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
// 恢复状态
|
||||
Position = position;
|
||||
FlipX = flipX;
|
||||
FlipY = flipY;
|
||||
|
||||
// 恢复原本 Track0 上所有动画
|
||||
if (savedTrack0 is not null)
|
||||
{
|
||||
var entry = animationState.SetAnimation(0, savedTrack0.Animation.Name, true);
|
||||
entry.TrackTime = savedTrack0.TrackTime;
|
||||
var savedEntry = savedTrack0.Next;
|
||||
while (savedEntry is not null)
|
||||
{
|
||||
entry = animationState.AddAnimation(0, savedEntry.Animation.Name, true, 0);
|
||||
entry.TrackTime = savedEntry.TrackTime;
|
||||
savedEntry = savedEntry.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override PointF Position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipX
|
||||
{
|
||||
get => skeleton.ScaleX < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value)
|
||||
skeleton.ScaleX *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipY
|
||||
{
|
||||
get => skeleton.ScaleY < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value)
|
||||
skeleton.ScaleY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override string CurrentAnimation
|
||||
{
|
||||
get => animationState.GetCurrent(0)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
set
|
||||
{
|
||||
if (value == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(0, EmptyAnimation, false);
|
||||
else if (animationNames.Contains(value))
|
||||
animationState.SetAnimation(0, value, true);
|
||||
Update(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
float[] _ = [];
|
||||
skeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
return new RectangleF(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
skeleton.Update(delta);
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
private SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
|
||||
public override void Draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices, 0);
|
||||
worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (meshAttachment.WorldVerticesLength > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.WorldVerticesLength / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is ClippingAttachment clippingAttachment)
|
||||
{
|
||||
clipping.ClipStart(slot, clippingAttachment);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
SFML.Graphics.BlendMode blendMode = GetSFMLBlendMode(slot.Data.BlendMode);
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
vertexArray.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
if (clipping.IsClipping)
|
||||
{
|
||||
// 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
clipping.ClipTriangles(worldVertices, worldVerticesCount * 2, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
worldVertices = clipping.ClippedVertices.Items;
|
||||
worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
uvs = clipping.ClippedUVs.Items;
|
||||
}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
vertexArray.Append(vertex);
|
||||
}
|
||||
|
||||
clipping.ClipEnd(slot);
|
||||
}
|
||||
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
clipping.ClipEnd();
|
||||
|
||||
// 包围盒
|
||||
if (IsDebug && IsSelected && DebugBounds)
|
||||
{
|
||||
var bounds = Bounds;
|
||||
boundsVertices[0] = boundsVertices[4] = new(new(bounds.Left, bounds.Top), BoundsColor);
|
||||
boundsVertices[1] = new(new(bounds.Right, bounds.Top), BoundsColor);
|
||||
boundsVertices[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor);
|
||||
boundsVertices[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor);
|
||||
target.Draw(boundsVertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,363 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime38;
|
||||
using SpineRuntime38.Attachments;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
[SpineImplementation(Version.V38)]
|
||||
internal class Spine38 : SpineViewer.Spine.Spine
|
||||
{
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private class TextureLoader : SpineRuntime38.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
page.width = (int)texture.Size.X;
|
||||
page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static TextureLoader textureLoader = new();
|
||||
|
||||
private Atlas atlas;
|
||||
private SkeletonBinary? skeletonBinary;
|
||||
private SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
private SkeletonClipping clipping = new();
|
||||
|
||||
public Spine38(string skelPath, string? atlasPath = null) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
foreach (var anime in skeletonData.Animations)
|
||||
animationNames.Add(anime.Name);
|
||||
|
||||
CurrentAnimation = DefaultAnimationName;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
public override float Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skeletonBinary is not null)
|
||||
return skeletonBinary.Scale;
|
||||
else if (skeletonJson is not null)
|
||||
return skeletonJson.Scale;
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
set
|
||||
{
|
||||
// 保存状态
|
||||
var position = Position;
|
||||
var flipX = FlipX;
|
||||
var flipY = FlipY;
|
||||
var savedTrack0 = animationState.GetCurrent(0);
|
||||
|
||||
var val = Math.Max(value, SCALE_MIN);
|
||||
if (skeletonBinary is not null)
|
||||
{
|
||||
skeletonBinary.Scale = val;
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
else if (skeletonJson is not null)
|
||||
{
|
||||
skeletonJson.Scale = val;
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
|
||||
// reload skel-dependent data
|
||||
animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix };
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
// 恢复状态
|
||||
Position = position;
|
||||
FlipX = flipX;
|
||||
FlipY = flipY;
|
||||
|
||||
// 恢复原本 Track0 上所有动画
|
||||
if (savedTrack0 is not null)
|
||||
{
|
||||
var entry = animationState.SetAnimation(0, savedTrack0.Animation.Name, true);
|
||||
entry.TrackTime = savedTrack0.TrackTime;
|
||||
var savedEntry = savedTrack0.Next;
|
||||
while (savedEntry is not null)
|
||||
{
|
||||
entry = animationState.AddAnimation(0, savedEntry.Animation.Name, true, 0);
|
||||
entry.TrackTime = savedEntry.TrackTime;
|
||||
savedEntry = savedEntry.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override PointF Position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipX
|
||||
{
|
||||
get => skeleton.ScaleX < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value)
|
||||
skeleton.ScaleX *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipY
|
||||
{
|
||||
get => skeleton.ScaleY < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value)
|
||||
skeleton.ScaleY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override string CurrentAnimation
|
||||
{
|
||||
get => animationState.GetCurrent(0)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
set
|
||||
{
|
||||
if (value == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(0, EmptyAnimation, false);
|
||||
else if (animationNames.Contains(value))
|
||||
animationState.SetAnimation(0, value, true);
|
||||
Update(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
float[] _ = [];
|
||||
skeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
return new RectangleF(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
skeleton.Update(delta);
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
private SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
|
||||
public override void Draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices, 0);
|
||||
worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (meshAttachment.WorldVerticesLength > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.WorldVerticesLength / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is ClippingAttachment clippingAttachment)
|
||||
{
|
||||
clipping.ClipStart(slot, clippingAttachment);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
SFML.Graphics.BlendMode blendMode = GetSFMLBlendMode(slot.Data.BlendMode);
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
vertexArray.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
if (clipping.IsClipping)
|
||||
{
|
||||
// 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
clipping.ClipTriangles(worldVertices, worldVerticesCount * 2, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
worldVertices = clipping.ClippedVertices.Items;
|
||||
worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
uvs = clipping.ClippedUVs.Items;
|
||||
}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
vertexArray.Append(vertex);
|
||||
}
|
||||
|
||||
clipping.ClipEnd(slot);
|
||||
}
|
||||
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
clipping.ClipEnd();
|
||||
|
||||
// 包围盒
|
||||
if (IsDebug && IsSelected && DebugBounds)
|
||||
{
|
||||
var bounds = Bounds;
|
||||
boundsVertices[0] = boundsVertices[4] = new(new(bounds.Left, bounds.Top), BoundsColor);
|
||||
boundsVertices[1] = new(new(bounds.Right, bounds.Top), BoundsColor);
|
||||
boundsVertices[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor);
|
||||
boundsVertices[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor);
|
||||
target.Draw(boundsVertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,362 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime40;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
[SpineImplementation(Version.V40)]
|
||||
internal class Spine40 : SpineViewer.Spine.Spine
|
||||
{
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private class TextureLoader : SpineRuntime40.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
page.width = (int)texture.Size.X;
|
||||
page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static TextureLoader textureLoader = new();
|
||||
|
||||
private Atlas atlas;
|
||||
private SkeletonBinary? skeletonBinary;
|
||||
private SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
private SkeletonClipping clipping = new();
|
||||
|
||||
public Spine40(string skelPath, string? atlasPath = null) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
foreach (var anime in skeletonData.Animations)
|
||||
animationNames.Add(anime.Name);
|
||||
|
||||
CurrentAnimation = DefaultAnimationName;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
public override float Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skeletonBinary is not null)
|
||||
return skeletonBinary.Scale;
|
||||
else if (skeletonJson is not null)
|
||||
return skeletonJson.Scale;
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
set
|
||||
{
|
||||
// 保存状态
|
||||
var position = Position;
|
||||
var flipX = FlipX;
|
||||
var flipY = FlipY;
|
||||
var savedTrack0 = animationState.GetCurrent(0);
|
||||
|
||||
var val = Math.Max(value, SCALE_MIN);
|
||||
if (skeletonBinary is not null)
|
||||
{
|
||||
skeletonBinary.Scale = val;
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
else if (skeletonJson is not null)
|
||||
{
|
||||
skeletonJson.Scale = val;
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
|
||||
// reload skel-dependent data
|
||||
animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix };
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
// 恢复状态
|
||||
Position = position;
|
||||
FlipX = flipX;
|
||||
FlipY = flipY;
|
||||
|
||||
// 恢复原本 Track0 上所有动画
|
||||
if (savedTrack0 is not null)
|
||||
{
|
||||
var entry = animationState.SetAnimation(0, savedTrack0.Animation.Name, true);
|
||||
entry.TrackTime = savedTrack0.TrackTime;
|
||||
var savedEntry = savedTrack0.Next;
|
||||
while (savedEntry is not null)
|
||||
{
|
||||
entry = animationState.AddAnimation(0, savedEntry.Animation.Name, true, 0);
|
||||
entry.TrackTime = savedEntry.TrackTime;
|
||||
savedEntry = savedEntry.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override PointF Position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipX
|
||||
{
|
||||
get => skeleton.ScaleX < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value)
|
||||
skeleton.ScaleX *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipY
|
||||
{
|
||||
get => skeleton.ScaleY < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value)
|
||||
skeleton.ScaleY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override string CurrentAnimation
|
||||
{
|
||||
get => animationState.GetCurrent(0)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
set
|
||||
{
|
||||
if (value == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(0, EmptyAnimation, false);
|
||||
else if (animationNames.Contains(value))
|
||||
animationState.SetAnimation(0, value, true);
|
||||
Update(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
float[] _ = [];
|
||||
skeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
return new RectangleF(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
skeleton.Update(delta);
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
private SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
|
||||
public override void Draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices, 0);
|
||||
worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (meshAttachment.WorldVerticesLength > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.WorldVerticesLength / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is ClippingAttachment clippingAttachment)
|
||||
{
|
||||
clipping.ClipStart(slot, clippingAttachment);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
SFML.Graphics.BlendMode blendMode = GetSFMLBlendMode(slot.Data.BlendMode);
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
vertexArray.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
if (clipping.IsClipping)
|
||||
{
|
||||
// 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
clipping.ClipTriangles(worldVertices, worldVerticesCount * 2, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
worldVertices = clipping.ClippedVertices.Items;
|
||||
worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
uvs = clipping.ClippedUVs.Items;
|
||||
}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
vertexArray.Append(vertex);
|
||||
}
|
||||
|
||||
clipping.ClipEnd(slot);
|
||||
}
|
||||
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
clipping.ClipEnd();
|
||||
|
||||
// 包围盒
|
||||
if (IsDebug && IsSelected && DebugBounds)
|
||||
{
|
||||
var bounds = Bounds;
|
||||
boundsVertices[0] = boundsVertices[4] = new(new(bounds.Left, bounds.Top), BoundsColor);
|
||||
boundsVertices[1] = new(new(bounds.Right, bounds.Top), BoundsColor);
|
||||
boundsVertices[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor);
|
||||
boundsVertices[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor);
|
||||
target.Draw(boundsVertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,362 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime41;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
[SpineImplementation(Version.V41)]
|
||||
internal class Spine41 : SpineViewer.Spine.Spine
|
||||
{
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private class TextureLoader : SpineRuntime41.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
page.width = (int)texture.Size.X;
|
||||
page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static TextureLoader textureLoader = new();
|
||||
|
||||
private Atlas atlas;
|
||||
private SkeletonBinary? skeletonBinary;
|
||||
private SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
private SkeletonClipping clipping = new();
|
||||
|
||||
public Spine41(string skelPath, string? atlasPath = null) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
foreach (var anime in skeletonData.Animations)
|
||||
animationNames.Add(anime.Name);
|
||||
|
||||
CurrentAnimation = DefaultAnimationName;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
public override float Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skeletonBinary is not null)
|
||||
return skeletonBinary.Scale;
|
||||
else if (skeletonJson is not null)
|
||||
return skeletonJson.Scale;
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
set
|
||||
{
|
||||
// 保存状态
|
||||
var position = Position;
|
||||
var flipX = FlipX;
|
||||
var flipY = FlipY;
|
||||
var savedTrack0 = animationState.GetCurrent(0);
|
||||
|
||||
var val = Math.Max(value, SCALE_MIN);
|
||||
if (skeletonBinary is not null)
|
||||
{
|
||||
skeletonBinary.Scale = val;
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
else if (skeletonJson is not null)
|
||||
{
|
||||
skeletonJson.Scale = val;
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
|
||||
// reload skel-dependent data
|
||||
animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix };
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
// 恢复状态
|
||||
Position = position;
|
||||
FlipX = flipX;
|
||||
FlipY = flipY;
|
||||
|
||||
// 恢复原本 Track0 上所有动画
|
||||
if (savedTrack0 is not null)
|
||||
{
|
||||
var entry = animationState.SetAnimation(0, savedTrack0.Animation.Name, true);
|
||||
entry.TrackTime = savedTrack0.TrackTime;
|
||||
var savedEntry = savedTrack0.Next;
|
||||
while (savedEntry is not null)
|
||||
{
|
||||
entry = animationState.AddAnimation(0, savedEntry.Animation.Name, true, 0);
|
||||
entry.TrackTime = savedEntry.TrackTime;
|
||||
savedEntry = savedEntry.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override PointF Position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipX
|
||||
{
|
||||
get => skeleton.ScaleX < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value)
|
||||
skeleton.ScaleX *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipY
|
||||
{
|
||||
get => skeleton.ScaleY < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value)
|
||||
skeleton.ScaleY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override string CurrentAnimation
|
||||
{
|
||||
get => animationState.GetCurrent(0)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
set
|
||||
{
|
||||
if (value == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(0, EmptyAnimation, false);
|
||||
else if (animationNames.Contains(value))
|
||||
animationState.SetAnimation(0, value, true);
|
||||
Update(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
float[] _ = [];
|
||||
skeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
return new RectangleF(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
//skeleton.Update(delta); // XXX: v4.1.x 没有 Update 方法
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
private SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
|
||||
public override void Draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.Region).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot, worldVertices, 0);
|
||||
worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.Region).page.rendererObject;
|
||||
|
||||
if (meshAttachment.WorldVerticesLength > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.WorldVerticesLength / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is ClippingAttachment clippingAttachment)
|
||||
{
|
||||
clipping.ClipStart(slot, clippingAttachment);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
SFML.Graphics.BlendMode blendMode = GetSFMLBlendMode(slot.Data.BlendMode);
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
vertexArray.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
if (clipping.IsClipping)
|
||||
{
|
||||
// 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
clipping.ClipTriangles(worldVertices, worldVerticesCount * 2, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
worldVertices = clipping.ClippedVertices.Items;
|
||||
worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
uvs = clipping.ClippedUVs.Items;
|
||||
}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
vertexArray.Append(vertex);
|
||||
}
|
||||
|
||||
clipping.ClipEnd(slot);
|
||||
}
|
||||
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
clipping.ClipEnd();
|
||||
|
||||
// 包围盒
|
||||
if (IsDebug && IsSelected && DebugBounds)
|
||||
{
|
||||
var bounds = Bounds;
|
||||
boundsVertices[0] = boundsVertices[4] = new(new(bounds.Left, bounds.Top), BoundsColor);
|
||||
boundsVertices[1] = new(new(bounds.Right, bounds.Top), BoundsColor);
|
||||
boundsVertices[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor);
|
||||
boundsVertices[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor);
|
||||
target.Draw(boundsVertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,362 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime42;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
[SpineImplementation(Version.V42)]
|
||||
internal class Spine42 : SpineViewer.Spine.Spine
|
||||
{
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private class TextureLoader : SpineRuntime42.TextureLoader
|
||||
{
|
||||
public void Load(AtlasPage page, string path)
|
||||
{
|
||||
var texture = new SFML.Graphics.Texture(path);
|
||||
if (page.magFilter == TextureFilter.Linear)
|
||||
texture.Smooth = true;
|
||||
if (page.uWrap == TextureWrap.Repeat && page.vWrap == TextureWrap.Repeat)
|
||||
texture.Repeated = true;
|
||||
|
||||
page.rendererObject = texture;
|
||||
page.width = (int)texture.Size.X;
|
||||
page.height = (int)texture.Size.Y;
|
||||
}
|
||||
|
||||
public void Unload(object texture)
|
||||
{
|
||||
((SFML.Graphics.Texture)texture).Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static TextureLoader textureLoader = new();
|
||||
|
||||
private Atlas atlas;
|
||||
private SkeletonBinary? skeletonBinary;
|
||||
private SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
private SkeletonClipping clipping = new();
|
||||
|
||||
public Spine42(string skelPath, string? atlasPath = null) : base(skelPath, atlasPath)
|
||||
{
|
||||
atlas = new Atlas(AtlasPath, textureLoader);
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
foreach (var anime in skeletonData.Animations)
|
||||
animationNames.Add(anime.Name);
|
||||
|
||||
CurrentAnimation = DefaultAnimationName;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
public override float Scale
|
||||
{
|
||||
get
|
||||
{
|
||||
if (skeletonBinary is not null)
|
||||
return skeletonBinary.Scale;
|
||||
else if (skeletonJson is not null)
|
||||
return skeletonJson.Scale;
|
||||
else
|
||||
return 1f;
|
||||
}
|
||||
set
|
||||
{
|
||||
// 保存状态
|
||||
var position = Position;
|
||||
var flipX = FlipX;
|
||||
var flipY = FlipY;
|
||||
var savedTrack0 = animationState.GetCurrent(0);
|
||||
|
||||
var val = Math.Max(value, SCALE_MIN);
|
||||
if (skeletonBinary is not null)
|
||||
{
|
||||
skeletonBinary.Scale = val;
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
else if (skeletonJson is not null)
|
||||
{
|
||||
skeletonJson.Scale = val;
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
|
||||
// reload skel-dependent data
|
||||
animationStateData = new AnimationStateData(skeletonData) { DefaultMix = animationStateData.DefaultMix };
|
||||
skeleton = new Skeleton(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
|
||||
// 恢复状态
|
||||
Position = position;
|
||||
FlipX = flipX;
|
||||
FlipY = flipY;
|
||||
|
||||
// 恢复原本 Track0 上所有动画
|
||||
if (savedTrack0 is not null)
|
||||
{
|
||||
var entry = animationState.SetAnimation(0, savedTrack0.Animation.Name, true);
|
||||
entry.TrackTime = savedTrack0.TrackTime;
|
||||
var savedEntry = savedTrack0.Next;
|
||||
while (savedEntry is not null)
|
||||
{
|
||||
entry = animationState.AddAnimation(0, savedEntry.Animation.Name, true, 0);
|
||||
entry.TrackTime = savedEntry.TrackTime;
|
||||
savedEntry = savedEntry.Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override PointF Position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipX
|
||||
{
|
||||
get => skeleton.ScaleX < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value)
|
||||
skeleton.ScaleX *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool FlipY
|
||||
{
|
||||
get => skeleton.ScaleY < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value)
|
||||
skeleton.ScaleY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override string CurrentAnimation
|
||||
{
|
||||
get => animationState.GetCurrent(0)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
set
|
||||
{
|
||||
if (value == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(0, EmptyAnimation, false);
|
||||
else if (animationNames.Contains(value))
|
||||
animationState.SetAnimation(0, value, true);
|
||||
Update(0);
|
||||
}
|
||||
}
|
||||
|
||||
public override RectangleF Bounds
|
||||
{
|
||||
get
|
||||
{
|
||||
float[] _ = [];
|
||||
skeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
return new RectangleF(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
skeleton.Update(delta);
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.UpdateWorldTransform(Skeleton.Physics.Update);
|
||||
}
|
||||
|
||||
private SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
|
||||
public override void Draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.Region).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot, worldVertices, 0);
|
||||
worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.Region).page.rendererObject;
|
||||
|
||||
if (meshAttachment.WorldVerticesLength > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.WorldVerticesLength / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is ClippingAttachment clippingAttachment)
|
||||
{
|
||||
clipping.ClipStart(slot, clippingAttachment);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
SFML.Graphics.BlendMode blendMode = GetSFMLBlendMode(slot.Data.BlendMode);
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
vertexArray.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
if (clipping.IsClipping)
|
||||
{
|
||||
// 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
clipping.ClipTriangles(worldVertices, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
worldVertices = clipping.ClippedVertices.Items;
|
||||
worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
uvs = clipping.ClippedUVs.Items;
|
||||
}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
vertexArray.Append(vertex);
|
||||
}
|
||||
|
||||
clipping.ClipEnd(slot);
|
||||
}
|
||||
|
||||
if (UsePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
target.Draw(vertexArray, states);
|
||||
clipping.ClipEnd();
|
||||
|
||||
// 包围盒
|
||||
if (IsDebug && IsSelected && DebugBounds)
|
||||
{
|
||||
var bounds = Bounds;
|
||||
boundsVertices[0] = boundsVertices[4] = new(new(bounds.Left, bounds.Top), BoundsColor);
|
||||
boundsVertices[1] = new(new(bounds.Right, bounds.Top), BoundsColor);
|
||||
boundsVertices[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor);
|
||||
boundsVertices[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor);
|
||||
target.Draw(boundsVertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
619
SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs
Normal file
619
SpineViewer/Spine/Implementations/SpineObject/SpineObject21.cs
Normal file
@@ -0,0 +1,619 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime21;
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Utils;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
{
|
||||
[SpineImplementation(SpineVersion.V21)]
|
||||
internal class SpineObject21 : Spine.SpineObject
|
||||
{
|
||||
//private static SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
//{
|
||||
// return spineBlendMode switch
|
||||
// {
|
||||
// BlendMode.Normal => BlendMode.Normal,
|
||||
// BlendMode.Additive => BlendMode.Additive,
|
||||
// BlendMode.Multiply => BlendMode.Multiply,
|
||||
// BlendMode.Screen => BlendMode.Screen,
|
||||
// _ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
// };
|
||||
//}
|
||||
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
private readonly SkeletonBinary? skeletonBinary;
|
||||
private readonly SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
// 2.1.x 不支持剪裁
|
||||
//private SkeletonClipping clipping = new();
|
||||
|
||||
/// <summary>
|
||||
/// 所有插槽在所有皮肤中可用的附件集合
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, Dictionary<string, Attachment>> slotAttachments = [];
|
||||
|
||||
public SpineObject21(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var sk in skeletonData.Skins)
|
||||
{
|
||||
foreach (var (k, att) in sk.Attachments)
|
||||
{
|
||||
var slotName = skeletonData.Slots[k.Key].Name;
|
||||
if (!slotAttachments.TryGetValue(slotName, out var attachments))
|
||||
slotAttachments[slotName] = attachments = new() { [EMPTY_ATTACHMENT] = null };
|
||||
attachments[att.Name] = att;
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
protected override float scale
|
||||
{
|
||||
get => Math.Abs(skeleton.ScaleX);
|
||||
set
|
||||
{
|
||||
skeleton.ScaleX = Math.Sign(skeleton.ScaleX) * value;
|
||||
skeleton.ScaleY = Math.Sign(skeleton.ScaleY) * value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override PointF position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool flipX
|
||||
{
|
||||
get => skeleton.ScaleX < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value)
|
||||
skeleton.ScaleX *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool flipY
|
||||
{
|
||||
get => skeleton.ScaleY < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value)
|
||||
skeleton.ScaleY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string getSlotAttachment(string slot) => skeleton.FindSlot(slot)?.Attachment?.Name ?? EMPTY_ATTACHMENT;
|
||||
|
||||
protected override void setSlotAttachment(string slot, string name)
|
||||
{
|
||||
if (slotAttachments.TryGetValue(slot, out var attachments)
|
||||
&& attachments.TryGetValue(name, out var att)
|
||||
&& skeleton.FindSlot(slot) is Slot s)
|
||||
s.Attachment = att;
|
||||
}
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
// XXX: 3.7 及以下不支持 AddSkin
|
||||
foreach (var (k, v) in sk.Attachments)
|
||||
skeleton.Skin.AddAttachment(k.Key, k.Value, v);
|
||||
}
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
skeleton.UpdateCache();
|
||||
}
|
||||
|
||||
protected override void clearSkins()
|
||||
{
|
||||
skeleton.Skin.Attachments.Clear();
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
skeleton.UpdateCache();
|
||||
}
|
||||
|
||||
protected override int[] getTrackIndices() => animationState.Tracks.Select((_, i) => i).Where(i => animationState.Tracks[i] is not null).ToArray();
|
||||
|
||||
protected override string getAnimation(int track) => animationState.GetCurrent(track)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
|
||||
protected override void setAnimation(int track, string name)
|
||||
{
|
||||
if (name == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(track, EmptyAnimation, true);
|
||||
else if (AnimationNames.Contains(name))
|
||||
animationState.SetAnimation(track, name, true);
|
||||
}
|
||||
|
||||
protected override void clearTrack(int i) => animationState.ClearTrack(i);
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
protected override RectangleF getCurrentBounds()
|
||||
{
|
||||
skeleton.GetBounds(out var x, out var y, out var w, out var h);
|
||||
return new RectangleF(x, y, w, h);
|
||||
}
|
||||
|
||||
protected override RectangleF getBounds()
|
||||
{
|
||||
// 初始化临时对象
|
||||
var maxDuration = 0f;
|
||||
var tmpSkeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) };
|
||||
var tmpAnimationState = new AnimationState(animationStateData);
|
||||
tmpSkeleton.ScaleX = skeleton.ScaleX;
|
||||
tmpSkeleton.ScaleY = skeleton.ScaleY;
|
||||
tmpSkeleton.X = skeleton.X;
|
||||
tmpSkeleton.Y = skeleton.Y;
|
||||
foreach (var (name, _) in skinLoadStatus.Where(e => e.Value))
|
||||
{
|
||||
foreach (var (k, v) in skeletonData.FindSkin(name).Attachments)
|
||||
tmpSkeleton.Skin.AddAttachment(k.Key, k.Value, v);
|
||||
}
|
||||
foreach (var tr in animationState.Tracks.Select((_, i) => i).Where(i => animationState.Tracks[i] is not null))
|
||||
{
|
||||
var ani = animationState.GetCurrent(tr).Animation;
|
||||
tmpAnimationState.SetAnimation(tr, ani, true);
|
||||
if (ani.Duration > maxDuration) maxDuration = ani.Duration;
|
||||
}
|
||||
tmpSkeleton.SetSlotsToSetupPose();
|
||||
tmpAnimationState.Update(0);
|
||||
tmpAnimationState.Apply(tmpSkeleton);
|
||||
tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
tmpAnimationState.Update(delta);
|
||||
tmpAnimationState.Apply(tmpSkeleton);
|
||||
tmpSkeleton.Update(delta);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
protected override void update(float delta)
|
||||
{
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.Update(delta);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
protected override void draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
triangleVertices.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = SFMLShader.GetSpineShader(usePma);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
//int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices);
|
||||
//worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (meshAttachment.Vertices.Length > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
//worldVerticesCount = meshAttachment.Vertices.Length / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)skinnedMeshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
//worldVerticesCount = skinnedMeshAttachment.Vertices.Length / 2;
|
||||
worldTriangleIndices = skinnedMeshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = skinnedMeshAttachment.Triangles.Length;
|
||||
uvs = skinnedMeshAttachment.UVs;
|
||||
tintR *= skinnedMeshAttachment.R;
|
||||
tintG *= skinnedMeshAttachment.G;
|
||||
tintB *= skinnedMeshAttachment.B;
|
||||
tintA *= skinnedMeshAttachment.A;
|
||||
}
|
||||
// 2.1.x 不支持剪裁
|
||||
//else if (attachment is ClippingAttachment clippingAttachment)
|
||||
//{
|
||||
// clipping.ClipStart(slot, clippingAttachment);
|
||||
// continue;
|
||||
//}
|
||||
else
|
||||
{
|
||||
//clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 似乎 2.1.x 也没有 BlendMode
|
||||
SFML.Graphics.BlendMode blendMode = slot.Data.AdditiveBlending ? SFMLBlendMode.AdditivePma : SFMLBlendMode.NormalPma;
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (triangleVertices.VertexCount > 0)
|
||||
{
|
||||
target.Draw(triangleVertices, states);
|
||||
triangleVertices.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
//if (clipping.IsClipping)
|
||||
//{
|
||||
// // 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
// clipping.ClipTriangles(worldVertices, worldVerticesCount * 2, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
// worldVertices = clipping.ClippedVertices.Items;
|
||||
// worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
// worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
// worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
// uvs = clipping.ClippedUVs.Items;
|
||||
//}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
triangleVertices.Append(vertex);
|
||||
}
|
||||
|
||||
//clipping.ClipEnd(slot);
|
||||
}
|
||||
//clipping.ClipEnd();
|
||||
|
||||
target.Draw(triangleVertices, states);
|
||||
}
|
||||
|
||||
protected override void debugDraw(SFML.Graphics.RenderTarget target)
|
||||
{
|
||||
lineVertices.Clear();
|
||||
rectLineVertices.Clear();
|
||||
|
||||
if (debugRegions)
|
||||
{
|
||||
SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor };
|
||||
foreach (var slot in skeleton.Slots)
|
||||
{
|
||||
if (slot.Attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVerticesBuffer);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[2];
|
||||
vt.Position.Y = worldVerticesBuffer[3];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[4];
|
||||
vt.Position.Y = worldVerticesBuffer[5];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[6];
|
||||
vt.Position.Y = worldVerticesBuffer[7];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debugMeshes)
|
||||
{
|
||||
SFML.Graphics.Vertex vt = new() { Color = MeshLineColor };
|
||||
foreach (var slot in skeleton.Slots)
|
||||
{
|
||||
if (slot.Attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
if (meshAttachment.Vertices.Length > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2];
|
||||
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var triangleIndices = meshAttachment.Triangles;
|
||||
for (int i = 0; i < triangleIndices.Length; i += 3)
|
||||
{
|
||||
var idx0 = triangleIndices[i] * 2;
|
||||
var idx1 = triangleIndices[i + 1] * 2;
|
||||
var idx2 = triangleIndices[i + 2] * 2;
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx1];
|
||||
vt.Position.Y = worldVerticesBuffer[idx1 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx2];
|
||||
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
else if (slot.Attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var triangleIndices = skinnedMeshAttachment.Triangles;
|
||||
for (int i = 0; i < triangleIndices.Length; i += 3)
|
||||
{
|
||||
var idx0 = triangleIndices[i] * 2;
|
||||
var idx1 = triangleIndices[i + 1] * 2;
|
||||
var idx2 = triangleIndices[i + 2] * 2;
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx1];
|
||||
vt.Position.Y = worldVerticesBuffer[idx1 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx2];
|
||||
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debugMeshHulls)
|
||||
{
|
||||
SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor };
|
||||
foreach (var slot in skeleton.Slots)
|
||||
{
|
||||
if (slot.Attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
if (meshAttachment.Vertices.Length > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[meshAttachment.Vertices.Length * 2];
|
||||
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var hullLength = (meshAttachment.HullLength >> 1) << 1;
|
||||
|
||||
if (debugMeshHulls && hullLength > 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
for (int i = 2; i < hullLength; i += 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[i];
|
||||
vt.Position.Y = worldVerticesBuffer[i + 1];
|
||||
lineVertices.Append(vt);
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
else if (slot.Attachment is SkinnedMeshAttachment skinnedMeshAttachment)
|
||||
{
|
||||
if (skinnedMeshAttachment.UVs.Length > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[skinnedMeshAttachment.UVs.Length * 2];
|
||||
|
||||
skinnedMeshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var hullLength = (skinnedMeshAttachment.HullLength >> 1) << 1;
|
||||
|
||||
if (debugMeshHulls && hullLength > 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
for (int i = 2; i < hullLength; i += 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[i];
|
||||
vt.Position.Y = worldVerticesBuffer[i + 1];
|
||||
lineVertices.Append(vt);
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debugBoundingBoxes)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
if (debugPaths)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
if (debugClippings) { } // 没有剪裁附件
|
||||
|
||||
if (debugBounds)
|
||||
{
|
||||
var vt = new SFML.Graphics.Vertex() { Color = BoundsColor };
|
||||
var b = getCurrentBounds();
|
||||
|
||||
vt.Position.X = b.Left;
|
||||
vt.Position.Y = b.Top;
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = b.Right;
|
||||
vt.Position.Y = b.Top;
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = b.Right;
|
||||
vt.Position.Y = b.Bottom;
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = b.Left;
|
||||
vt.Position.Y = b.Bottom;
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = b.Left;
|
||||
vt.Position.Y = b.Top;
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
|
||||
// 骨骼线放最后画
|
||||
if (debugBones)
|
||||
{
|
||||
var width = scale;
|
||||
foreach (var bone in skeleton.Bones)
|
||||
{
|
||||
var boneLength = bone.Data.Length;
|
||||
var p1 = new SFML.System.Vector2f(bone.WorldX, bone.WorldY);
|
||||
var p2 = new SFML.System.Vector2f(bone.WorldX + boneLength * bone.M00, bone.WorldY + boneLength * bone.M10);
|
||||
AddRectLine(p1, p2, BoneLineColor, width);
|
||||
}
|
||||
}
|
||||
|
||||
target.Draw(lineVertices);
|
||||
target.Draw(rectLineVertices);
|
||||
|
||||
// 骨骼的点最后画, 层级处于骨骼线上面
|
||||
if (debugBones)
|
||||
{
|
||||
var radius = scale;
|
||||
foreach (var bone in skeleton.Bones)
|
||||
{
|
||||
DrawCirclePoint(target, new(bone.WorldX, bone.WorldY), BonePointColor, radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
571
SpineViewer/Spine/Implementations/SpineObject/SpineObject36.cs
Normal file
571
SpineViewer/Spine/Implementations/SpineObject/SpineObject36.cs
Normal file
@@ -0,0 +1,571 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SpineRuntime36;
|
||||
using SpineViewer.Extensions;
|
||||
using SpineViewer.Utils;
|
||||
|
||||
namespace SpineViewer.Spine.Implementations.SpineObject
|
||||
{
|
||||
[SpineImplementation(SpineVersion.V36)]
|
||||
internal class SpineObject36 : Spine.SpineObject
|
||||
{
|
||||
private static SFML.Graphics.BlendMode GetSFMLBlendMode(BlendMode spineBlendMode)
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => SFMLBlendMode.NormalPma,
|
||||
BlendMode.Additive => SFMLBlendMode.AdditivePma,
|
||||
BlendMode.Multiply => SFMLBlendMode.MultiplyPma,
|
||||
BlendMode.Screen => SFMLBlendMode.ScreenPma,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly Animation EmptyAnimation = new(EMPTY_ANIMATION, [], 0);
|
||||
|
||||
private readonly Atlas atlas;
|
||||
private readonly SkeletonBinary? skeletonBinary;
|
||||
private readonly SkeletonJson? skeletonJson;
|
||||
private SkeletonData skeletonData;
|
||||
private AnimationStateData animationStateData;
|
||||
|
||||
private Skeleton skeleton;
|
||||
private AnimationState animationState;
|
||||
|
||||
private readonly SkeletonClipping clipping = new();
|
||||
|
||||
/// <summary>
|
||||
/// 所有插槽在所有皮肤中可用的附件集合
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, Dictionary<string, Attachment>> slotAttachments = [];
|
||||
|
||||
public SpineObject36(string skelPath, string atlasPath) : base(skelPath, atlasPath)
|
||||
{
|
||||
try { atlas = new Atlas(AtlasPath, textureLoader); }
|
||||
catch (Exception ex) { throw new InvalidDataException($"Failed to load atlas '{atlasPath}'", ex); }
|
||||
try
|
||||
{
|
||||
// 先尝试二进制文件
|
||||
skeletonJson = null;
|
||||
skeletonBinary = new SkeletonBinary(atlas);
|
||||
skeletonData = skeletonBinary.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
// 再尝试 Json 文件
|
||||
skeletonBinary = null;
|
||||
skeletonJson = new SkeletonJson(atlas);
|
||||
skeletonData = skeletonJson.ReadSkeletonData(SkelPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 都不行就报错
|
||||
atlas.Dispose();
|
||||
throw new InvalidDataException($"Unknown skeleton file format {SkelPath}");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var sk in skeletonData.Skins)
|
||||
{
|
||||
foreach (var (k, att) in sk.Attachments)
|
||||
{
|
||||
var slotName = skeletonData.Slots.Items[k.slotIndex].Name;
|
||||
if (!slotAttachments.TryGetValue(slotName, out var attachments))
|
||||
slotAttachments[slotName] = attachments = new() { [EMPTY_ATTACHMENT] = null };
|
||||
attachments[att.Name] = att;
|
||||
}
|
||||
}
|
||||
SlotAttachmentNames = slotAttachments.ToFrozenDictionary(item => item.Key, item => item.Value.Keys.ToImmutableArray());
|
||||
SkinNames = skeletonData.Skins.Select(v => v.Name).ToImmutableArray();
|
||||
AnimationNames = [EMPTY_ANIMATION, .. skeletonData.Animations.Select(v => v.Name)];
|
||||
|
||||
skeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) }; // 挂载一个空皮肤当作容器
|
||||
animationStateData = new AnimationStateData(skeletonData);
|
||||
animationState = new AnimationState(animationStateData);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose(disposing);
|
||||
atlas?.Dispose();
|
||||
}
|
||||
|
||||
public override string FileVersion { get => skeletonData.Version; }
|
||||
|
||||
protected override float scale
|
||||
{
|
||||
get => Math.Abs(skeleton.ScaleX);
|
||||
set
|
||||
{
|
||||
skeleton.ScaleX = Math.Sign(skeleton.ScaleX) * value;
|
||||
skeleton.ScaleY = Math.Sign(skeleton.ScaleY) * value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override PointF position
|
||||
{
|
||||
get => new(skeleton.X, skeleton.Y);
|
||||
set
|
||||
{
|
||||
skeleton.X = value.X;
|
||||
skeleton.Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool flipX
|
||||
{
|
||||
get => skeleton.ScaleX < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleX > 0 && value || skeleton.ScaleX < 0 && !value)
|
||||
skeleton.ScaleX *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool flipY
|
||||
{
|
||||
get => skeleton.ScaleY < 0;
|
||||
set
|
||||
{
|
||||
if (skeleton.ScaleY > 0 && value || skeleton.ScaleY < 0 && !value)
|
||||
skeleton.ScaleY *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected override string getSlotAttachment(string slot) => skeleton.FindSlot(slot)?.Attachment?.Name ?? EMPTY_ATTACHMENT;
|
||||
|
||||
protected override void setSlotAttachment(string slot, string name)
|
||||
{
|
||||
if (slotAttachments.TryGetValue(slot, out var attachments)
|
||||
&& attachments.TryGetValue(name, out var att)
|
||||
&& skeleton.FindSlot(slot) is Slot s)
|
||||
s.Attachment = att;
|
||||
}
|
||||
|
||||
protected override void addSkin(string name)
|
||||
{
|
||||
// default 不需要加载
|
||||
if (name != "default" && skeletonData.FindSkin(name) is Skin sk)
|
||||
{
|
||||
// XXX: 3.7 及以下不支持 AddSkin
|
||||
foreach (var (k, v) in sk.Attachments)
|
||||
skeleton.Skin.AddAttachment(k.slotIndex, k.name, v);
|
||||
}
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
skeleton.UpdateCache();
|
||||
}
|
||||
|
||||
protected override void clearSkins()
|
||||
{
|
||||
skeleton.Skin.Attachments.Clear();
|
||||
skeleton.SetSlotsToSetupPose();
|
||||
skeleton.UpdateCache();
|
||||
}
|
||||
|
||||
protected override int[] getTrackIndices() => animationState.Tracks.Select((_, i) => i).Where(i => animationState.Tracks.Items[i] is not null).ToArray();
|
||||
|
||||
protected override string getAnimation(int track) => animationState.GetCurrent(track)?.Animation.Name ?? EMPTY_ANIMATION;
|
||||
|
||||
protected override void setAnimation(int track, string name)
|
||||
{
|
||||
if (name == EMPTY_ANIMATION)
|
||||
animationState.SetAnimation(track, EmptyAnimation, true);
|
||||
else if (AnimationNames.Contains(name))
|
||||
animationState.SetAnimation(track, name, true);
|
||||
}
|
||||
|
||||
protected override void clearTrack(int i) => animationState.ClearTrack(i);
|
||||
|
||||
public override float GetAnimationDuration(string name) { return skeletonData.FindAnimation(name)?.Duration ?? 0f; }
|
||||
|
||||
protected override RectangleF getCurrentBounds()
|
||||
{
|
||||
float[] _ = [];
|
||||
skeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
return new RectangleF(x, y, w, h);
|
||||
}
|
||||
|
||||
protected override RectangleF getBounds()
|
||||
{
|
||||
// 初始化临时对象
|
||||
var maxDuration = 0f;
|
||||
var tmpSkeleton = new Skeleton(skeletonData) { Skin = new(Guid.NewGuid().ToString()) };
|
||||
var tmpAnimationState = new AnimationState(animationStateData);
|
||||
tmpSkeleton.ScaleX = skeleton.ScaleX;
|
||||
tmpSkeleton.ScaleY = skeleton.ScaleY;
|
||||
tmpSkeleton.X = skeleton.X;
|
||||
tmpSkeleton.Y = skeleton.Y;
|
||||
foreach (var (name, _) in skinLoadStatus.Where(e => e.Value))
|
||||
{
|
||||
foreach (var (k, v) in skeletonData.FindSkin(name).Attachments)
|
||||
tmpSkeleton.Skin.AddAttachment(k.slotIndex, k.name, v);
|
||||
}
|
||||
foreach (var tr in animationState.Tracks.Select((_, i) => i).Where(i => animationState.Tracks.Items[i] is not null))
|
||||
{
|
||||
var ani = animationState.GetCurrent(tr).Animation;
|
||||
tmpAnimationState.SetAnimation(tr, ani, true);
|
||||
if (ani.Duration > maxDuration) maxDuration = ani.Duration;
|
||||
}
|
||||
tmpSkeleton.SetSlotsToSetupPose();
|
||||
tmpAnimationState.Update(0);
|
||||
tmpAnimationState.Apply(tmpSkeleton);
|
||||
tmpSkeleton.Update(0);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
|
||||
// 按 100 帧每秒计算边框
|
||||
var bounds = getCurrentBounds();
|
||||
float[] _ = [];
|
||||
for (float tick = 0, delta = 0.01f; tick < maxDuration; tick += delta)
|
||||
{
|
||||
tmpSkeleton.GetBounds(out var x, out var y, out var w, out var h, ref _);
|
||||
bounds = bounds.Union(new(x, y, w, h));
|
||||
tmpAnimationState.Update(delta);
|
||||
tmpAnimationState.Apply(tmpSkeleton);
|
||||
tmpSkeleton.Update(delta);
|
||||
tmpSkeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
protected override void update(float delta)
|
||||
{
|
||||
animationState.Update(delta);
|
||||
animationState.Apply(skeleton);
|
||||
skeleton.Update(delta);
|
||||
skeleton.UpdateWorldTransform();
|
||||
}
|
||||
|
||||
protected override void draw(SFML.Graphics.RenderTarget target, SFML.Graphics.RenderStates states)
|
||||
{
|
||||
triangleVertices.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = SFMLShader.GetSpineShader(usePma);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
{
|
||||
var attachment = slot.Attachment;
|
||||
|
||||
SFML.Graphics.Texture texture;
|
||||
|
||||
float[] worldVertices = worldVerticesBuffer; // 顶点世界坐标, 连续的 [x0, y0, x1, y1, ...] 坐标值
|
||||
int worldVerticesCount; // 等于顶点数组的长度除以 2
|
||||
int[] worldTriangleIndices; // 三角形索引, 从顶点坐标数组取的时候要乘以 2, 最大值是 worldVerticesCount - 1
|
||||
int worldTriangleIndicesLength; // 三角形索引数组长度
|
||||
float[] uvs; // 纹理坐标
|
||||
float tintR = skeleton.R * slot.R;
|
||||
float tintG = skeleton.G * slot.G;
|
||||
float tintB = skeleton.B * slot.B;
|
||||
float tintA = skeleton.A * slot.A;
|
||||
|
||||
if (attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)regionAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVertices, 0);
|
||||
worldVerticesCount = 4;
|
||||
worldTriangleIndices = [0, 1, 2, 2, 3, 0];
|
||||
worldTriangleIndicesLength = 6;
|
||||
uvs = regionAttachment.UVs;
|
||||
tintR *= regionAttachment.R;
|
||||
tintG *= regionAttachment.G;
|
||||
tintB *= regionAttachment.B;
|
||||
tintA *= regionAttachment.A;
|
||||
}
|
||||
else if (attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
texture = (SFML.Graphics.Texture)((AtlasRegion)meshAttachment.RendererObject).page.rendererObject;
|
||||
|
||||
if (meshAttachment.WorldVerticesLength > worldVertices.Length)
|
||||
worldVertices = worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVertices);
|
||||
worldVerticesCount = meshAttachment.WorldVerticesLength / 2;
|
||||
worldTriangleIndices = meshAttachment.Triangles;
|
||||
worldTriangleIndicesLength = meshAttachment.Triangles.Length;
|
||||
uvs = meshAttachment.UVs;
|
||||
tintR *= meshAttachment.R;
|
||||
tintG *= meshAttachment.G;
|
||||
tintB *= meshAttachment.B;
|
||||
tintA *= meshAttachment.A;
|
||||
}
|
||||
else if (attachment is ClippingAttachment clippingAttachment)
|
||||
{
|
||||
clipping.ClipStart(slot, clippingAttachment);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipping.ClipEnd(slot);
|
||||
continue;
|
||||
}
|
||||
|
||||
SFML.Graphics.BlendMode blendMode = GetSFMLBlendMode(slot.Data.BlendMode);
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (triangleVertices.VertexCount > 0)
|
||||
{
|
||||
target.Draw(triangleVertices, states);
|
||||
triangleVertices.Clear();
|
||||
}
|
||||
states.BlendMode = blendMode;
|
||||
states.Texture = texture;
|
||||
}
|
||||
|
||||
if (clipping.IsClipping)
|
||||
{
|
||||
// 这里必须单独记录 Count, 和 Items 的 Length 是不一致的
|
||||
clipping.ClipTriangles(worldVertices, worldVerticesCount * 2, worldTriangleIndices, worldTriangleIndicesLength, uvs);
|
||||
worldVertices = clipping.ClippedVertices.Items;
|
||||
worldVerticesCount = clipping.ClippedVertices.Count / 2;
|
||||
worldTriangleIndices = clipping.ClippedTriangles.Items;
|
||||
worldTriangleIndicesLength = clipping.ClippedTriangles.Count;
|
||||
uvs = clipping.ClippedUVs.Items;
|
||||
}
|
||||
|
||||
var textureSizeX = texture.Size.X;
|
||||
var textureSizeY = texture.Size.Y;
|
||||
|
||||
SFML.Graphics.Vertex vertex = new();
|
||||
vertex.Color.R = (byte)(tintR * 255);
|
||||
vertex.Color.G = (byte)(tintG * 255);
|
||||
vertex.Color.B = (byte)(tintB * 255);
|
||||
vertex.Color.A = (byte)(tintA * 255);
|
||||
|
||||
// 必须用 worldTriangleIndicesLength 不能直接 foreach
|
||||
for (int i = 0; i < worldTriangleIndicesLength; i++)
|
||||
{
|
||||
var index = worldTriangleIndices[i] * 2;
|
||||
vertex.Position.X = worldVertices[index];
|
||||
vertex.Position.Y = worldVertices[index + 1];
|
||||
vertex.TexCoords.X = uvs[index] * textureSizeX;
|
||||
vertex.TexCoords.Y = uvs[index + 1] * textureSizeY;
|
||||
triangleVertices.Append(vertex);
|
||||
}
|
||||
|
||||
clipping.ClipEnd(slot);
|
||||
}
|
||||
clipping.ClipEnd();
|
||||
|
||||
target.Draw(triangleVertices, states);
|
||||
}
|
||||
|
||||
protected override void debugDraw(SFML.Graphics.RenderTarget target)
|
||||
{
|
||||
lineVertices.Clear();
|
||||
rectLineVertices.Clear();
|
||||
|
||||
if (debugRegions)
|
||||
{
|
||||
SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor };
|
||||
foreach (var slot in skeleton.Slots)
|
||||
{
|
||||
if (slot.Attachment is RegionAttachment regionAttachment)
|
||||
{
|
||||
regionAttachment.ComputeWorldVertices(slot.Bone, worldVerticesBuffer, 0);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[2];
|
||||
vt.Position.Y = worldVerticesBuffer[3];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[4];
|
||||
vt.Position.Y = worldVerticesBuffer[5];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[6];
|
||||
vt.Position.Y = worldVerticesBuffer[7];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debugMeshes)
|
||||
{
|
||||
SFML.Graphics.Vertex vt = new() { Color = MeshLineColor };
|
||||
foreach (var slot in skeleton.Slots)
|
||||
{
|
||||
if (slot.Attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var triangleIndices = meshAttachment.Triangles;
|
||||
for (int i = 0; i < triangleIndices.Length; i += 3)
|
||||
{
|
||||
var idx0 = triangleIndices[i] * 2;
|
||||
var idx1 = triangleIndices[i + 1] * 2;
|
||||
var idx2 = triangleIndices[i + 2] * 2;
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx1];
|
||||
vt.Position.Y = worldVerticesBuffer[idx1 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx2];
|
||||
vt.Position.Y = worldVerticesBuffer[idx2 + 1];
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[idx0];
|
||||
vt.Position.Y = worldVerticesBuffer[idx0 + 1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debugMeshHulls)
|
||||
{
|
||||
SFML.Graphics.Vertex vt = new() { Color = AttachmentLineColor };
|
||||
foreach (var slot in skeleton.Slots)
|
||||
{
|
||||
if (slot.Attachment is MeshAttachment meshAttachment)
|
||||
{
|
||||
if (meshAttachment.WorldVerticesLength > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = new float[meshAttachment.WorldVerticesLength * 2];
|
||||
|
||||
meshAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
var hullLength = (meshAttachment.HullLength >> 1) << 1;
|
||||
|
||||
if (debugMeshHulls && hullLength > 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
for (int i = 2; i < hullLength; i += 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[i];
|
||||
vt.Position.Y = worldVerticesBuffer[i + 1];
|
||||
lineVertices.Append(vt);
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debugBoundingBoxes)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
if (debugPaths)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
if (debugClippings)
|
||||
{
|
||||
SFML.Graphics.Vertex vt = new() { Color = ClippingLineColor };
|
||||
foreach (var slot in skeleton.Slots)
|
||||
{
|
||||
if (slot.Attachment is ClippingAttachment clippingAttachment)
|
||||
{
|
||||
if (clippingAttachment.WorldVerticesLength > worldVerticesBuffer.Length)
|
||||
worldVerticesBuffer = worldVerticesBuffer = new float[clippingAttachment.WorldVerticesLength * 2];
|
||||
|
||||
clippingAttachment.ComputeWorldVertices(slot, worldVerticesBuffer);
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
|
||||
for (int i = 2; i < clippingAttachment.WorldVerticesLength; i += 2)
|
||||
{
|
||||
vt.Position.X = worldVerticesBuffer[i];
|
||||
vt.Position.Y = worldVerticesBuffer[i + 1];
|
||||
lineVertices.Append(vt);
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
|
||||
vt.Position.X = worldVerticesBuffer[0];
|
||||
vt.Position.Y = worldVerticesBuffer[1];
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debugBounds)
|
||||
{
|
||||
var vt = new SFML.Graphics.Vertex() { Color = BoundsColor };
|
||||
var b = getCurrentBounds();
|
||||
|
||||
vt.Position.X = b.Left;
|
||||
vt.Position.Y = b.Top;
|
||||
lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = b.Right;
|
||||
vt.Position.Y = b.Top;
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = b.Right;
|
||||
vt.Position.Y = b.Bottom;
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = b.Left;
|
||||
vt.Position.Y = b.Bottom;
|
||||
lineVertices.Append(vt); lineVertices.Append(vt);
|
||||
|
||||
vt.Position.X = b.Left;
|
||||
vt.Position.Y = b.Top;
|
||||
lineVertices.Append(vt);
|
||||
}
|
||||
|
||||
// 骨骼线放最后画
|
||||
if (debugBones)
|
||||
{
|
||||
var width = scale;
|
||||
foreach (var bone in skeleton.Bones)
|
||||
{
|
||||
var boneLength = bone.Data.Length;
|
||||
var p1 = new SFML.System.Vector2f(bone.WorldX, bone.WorldY);
|
||||
var p2 = new SFML.System.Vector2f(bone.WorldX + boneLength * bone.A, bone.WorldY + boneLength * bone.C);
|
||||
AddRectLine(p1, p2, BoneLineColor, width);
|
||||
}
|
||||
}
|
||||
|
||||
target.Draw(lineVertices);
|
||||
target.Draw(rectLineVertices);
|
||||
|
||||
// 骨骼的点最后画, 层级处于骨骼线上面
|
||||
if (debugBones)
|
||||
{
|
||||
var radius = scale;
|
||||
foreach (var bone in skeleton.Bones)
|
||||
{
|
||||
DrawCirclePoint(target, new(bone.WorldX, bone.WorldY), BonePointColor, radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user