Compare commits

...

298 Commits

Author SHA1 Message Date
ww-rm
2fecf4223a 更新至v0.12.17 2025-06-14 20:08:54 +08:00
ww-rm
2953ec44fb update changelog 2025-06-14 20:08:45 +08:00
ww-rm
77399b4524 改善动画边界检测 2025-06-14 20:07:09 +08:00
ww-rm
c0e2bb81e5 更新至v0.12.16 2025-06-11 13:41:25 +08:00
ww-rm
55ebcc1857 合并导出时也允许自动时长 2025-06-11 13:38:55 +08:00
ww-rm
292ede8461 修复工作流错误 2025-05-28 18:22:33 +08:00
ww-rm
63ed8d7ca4 修复工作流错误 2025-05-28 17:27:55 +08:00
ww-rm
ce7c6f3802 修复工作流错误 2025-05-28 17:14:08 +08:00
ww-rm
0b478cab18 修复工作流错误 2025-05-28 17:09:58 +08:00
ww-rm
b7f5f24e6f Merge branch 'dev/wf' of github.com:ww-rm/SpineViewer into dev/wf 2025-05-28 16:59:51 +08:00
ww-rm
150331d2e4 修复工作流错误 2025-05-28 16:59:38 +08:00
ww-rm
4d1aec9ed8 Merge branch 'release/wf' into dev/wf 2025-05-28 16:45:42 +08:00
ww-rm
0cb325820b 修复工作流版本提取错误 2025-05-28 16:38:00 +08:00
ww-rm
2a862b28be 更改工作流自动获取版本号 2025-05-28 16:29:29 +08:00
ww-rm
c2935f49e9 更新至v0.12.15 2025-05-28 16:29:29 +08:00
ww-rm
22043f8f38 update changelog 2025-05-28 16:29:29 +08:00
ww-rm
3020a818f0 修复附件类型枚举量的字符串大小写问题 2025-05-28 16:29:29 +08:00
ww-rm
30177e8d7f 更改工作流自动获取版本号 2025-05-28 16:28:12 +08:00
ww-rm
3ad49838be 更新至v0.12.15 2025-05-28 16:05:55 +08:00
ww-rm
3e480abd44 update changelog 2025-05-28 16:05:42 +08:00
ww-rm
49f6b28aef 修复附件类型枚举量的字符串大小写问题 2025-05-28 16:05:09 +08:00
ww-rm
b81d13b582 更新至v0.12.14 2025-05-28 09:13:03 +08:00
ww-rm
04eb3cb640 update changelog 2025-05-28 09:12:37 +08:00
ww-rm
0ac75a088a 修复curve读取错误 2025-05-28 09:11:25 +08:00
ww-rm
cd652a72a1 更新至v0.12.13 2025-05-19 10:31:34 +08:00
ww-rm
828ff30dbf update changelog 2025-05-19 10:31:15 +08:00
ww-rm
f452fe8a71 生成文件增加额外的随机后缀 2025-05-19 10:30:29 +08:00
ww-rm
15e29a3b8a 修复readattachmentline里的顺序错误 2025-05-17 10:47:49 +08:00
ww-rm
5c6e98f5e1 更新至v0.12.12 2025-05-13 14:21:13 +08:00
ww-rm
ef06073119 update changelog 2025-05-13 14:19:52 +08:00
ww-rm
bca8b0ad85 补充SkinnedMeshAttachment附件的渲染 2025-05-13 14:19:15 +08:00
ww-rm
4983b1fa88 更新至v0.12.11 2025-05-08 18:35:23 +08:00
ww-rm
f6b6d9f0e7 update changelog 2025-05-08 18:35:12 +08:00
ww-rm
12a168df92 修复atlas null 引用导致的闪退 2025-05-08 18:34:43 +08:00
ww-rm
e06d2012d6 更新至v0.12.10 2025-05-07 17:45:07 +08:00
ww-rm
faed2448eb update changelog 2025-05-07 17:44:52 +08:00
ww-rm
a80aed54a0 增加纹理加载菜单选项 2025-05-07 17:43:55 +08:00
ww-rm
3f9c4dfe99 抽出TextureLoader,增加部分可调参数 2025-05-07 17:43:42 +08:00
ww-rm
3c91f335fc 修复skin索引顺序问题 2025-05-06 19:11:46 +08:00
ww-rm
1ea4586360 Merge pull request #21 from steve14608/main
4.1版本格式转换,以及4.2版本发现的一些小bug
2025-05-02 16:29:23 +08:00
YongQi Li
45e08b5b60 Merge branch 'main' of https://github.com/steve14608/SpineViewer 2025-05-02 16:25:53 +08:00
YongQi Li
43ce5a5288 修改了skin2idx的读取逻辑 2025-05-02 16:25:39 +08:00
YongQi Li
887315ceda Merge branch 'main' of https://github.com/steve14608/SpineViewer 2025-05-02 14:52:01 +08:00
ww-rm
30b5c8dd74 4.1的格式转换 2025-05-02 14:51:40 +08:00
ww-rm
ef7ef76a59 更新至v0.12.9 2025-05-01 22:40:59 +08:00
ww-rm
a9834bcc13 update changelog 2025-05-01 22:40:38 +08:00
ww-rm
ec2752464d 修复部分情况下为调用UpdateCache导致皮肤设置失败 2025-05-01 22:38:55 +08:00
ww-rm
7b6a9b2a0f 更新至v0.12.8 2025-05-01 20:56:02 +08:00
ww-rm
8eda4f0849 update readme 2025-05-01 20:55:43 +08:00
ww-rm
cde25214ae update changelog 2025-05-01 20:55:10 +08:00
ww-rm
9f1f66776c 修复浮点数转换问题 2025-05-01 20:52:55 +08:00
ww-rm
c93b78528d 修复浮点数转换问题 2025-05-01 20:49:29 +08:00
ww-rm
e567e61383 修复写入问题 2025-05-01 20:17:17 +08:00
ww-rm
7c3184d88a 修改 Write 输入类型 2025-05-01 17:07:04 +08:00
ww-rm
e6f38657a3 修复path constraints target错误 2025-05-01 00:28:10 +08:00
ww-rm
ebcd61a9a2 fix ConvertFileFormatDialog localization 2025-04-30 11:08:05 +08:00
ww-rm
179fbfe84f 修改默认值写入范式 2025-04-30 02:19:43 +08:00
ww-rm
79441abff3 fix some text and shortcut keys 2025-04-29 16:23:59 +08:00
ww-rm
c3db8cd4ea Merge pull request #17 from myssal/main
feat: english localization
2025-04-29 16:08:56 +08:00
Myssal
27c58ffd87 fix: remove duplicate elements 2025-04-29 01:57:29 +07:00
Myssal
244249db2b fix: displayResolution typo 2025-04-29 01:10:53 +07:00
Myssal
33b937da87 fix: use check and ignore action instead of disable item 2025-04-29 01:04:06 +07:00
ww-rm
058834e8a6 修复读取部分问题 2025-04-28 23:45:01 +08:00
ww-rm
b134af3727 small change 2025-04-28 23:44:50 +08:00
ww-rm
6d2eafb4f1 add SkeletonConverter42 2025-04-28 20:30:01 +08:00
ww-rm
9f618804df 明确null类型 2025-04-28 20:21:31 +08:00
Myssal
61a3a62b65 Merge pull request #1 from myssal/feat/en_localization
Feat: English localization
2025-04-28 01:26:57 +07:00
Myssal
ced25dec87 feat: tooltip button in previewpanel localize 2025-04-28 01:23:22 +07:00
Myssal
60d5f3361a feat: main form localize 2025-04-28 01:15:10 +07:00
Myssal
c8ee4cf0c9 feat: spine exporter localize 2025-04-28 01:03:18 +07:00
Myssal
177434e503 feat: spineview localize 2025-04-28 00:08:25 +07:00
Myssal
58b45cde31 feat: spineview localize 2025-04-27 23:48:36 +07:00
Myssal
ff87030894 fix: parse constructor parameter to field 2025-04-27 23:18:49 +07:00
Myssal
7635adf637 feat: messagebox title localize 2025-04-27 22:06:45 +07:00
Myssal
ca7a40044c feat: more controls localize 2025-04-27 21:57:53 +07:00
Myssal
ce5be30f1d feat: localize model parameters 2025-04-27 21:01:54 +07:00
Myssal
1cb8f077f5 feat: localize propertygrid class 2025-04-27 21:01:31 +07:00
Myssal
61794cf784 feat: localize forms, controls, dialogs. 2025-04-27 19:52:56 +07:00
Myssal
045b191e4d feat: correct culture and set message box based on localize 2025-04-27 18:42:57 +07:00
Myssal
6116f6a4be feat: base function to switch language 2025-04-26 23:16:11 +07:00
ww-rm
ca7e94a306 update win32 2025-04-26 15:23:50 +08:00
ww-rm
165be38cfe update changelog 2025-04-26 15:14:19 +08:00
ww-rm
f1fb5fe5e1 更新至v0.12.7 2025-04-26 15:13:32 +08:00
ww-rm
17554d3a8e 补充遗漏的方法 2025-04-26 15:13:17 +08:00
ww-rm
054ac3939b 修改函数调用 2025-04-26 15:04:09 +08:00
ww-rm
9566c0a6f5 修复跨线程调用问题 2025-04-26 13:27:08 +08:00
ww-rm
b8509ccb69 修正事件处理 2025-04-25 22:08:11 +08:00
ww-rm
1e043e4faa update readme 2025-04-23 15:19:09 +08:00
ww-rm
5b1c177f58 增加ScaleX和ScaleY 2025-04-22 23:54:20 +08:00
ww-rm
794de783db 设置空动画为循环避免空引用 2025-04-21 21:29:24 +08:00
ww-rm
7f6aa26986 补充注释 2025-04-21 00:54:04 +08:00
ww-rm
fcd809fda5 使用PerMonitorV2 2025-04-20 23:13:37 +08:00
ww-rm
71ff8007fb update preview 2025-04-20 21:04:42 +08:00
ww-rm
a8261f4f58 update readme 2025-04-20 21:01:24 +08:00
ww-rm
bb6a6f3664 small change 2025-04-20 17:26:26 +08:00
ww-rm
9c6af07d32 去除切换里的窗口显示 2025-04-20 17:24:38 +08:00
ww-rm
afc011adbb update readme 2025-04-20 17:10:06 +08:00
ww-rm
da42c14d35 更新至0.12.6 2025-04-20 17:09:46 +08:00
ww-rm
a7438e2026 update changelog 2025-04-20 17:09:25 +08:00
ww-rm
47e5314bb3 禁用用户关闭事件 2025-04-20 17:09:13 +08:00
ww-rm
1978c1da11 update changelog 2025-04-20 16:57:09 +08:00
ww-rm
914c9d0ea3 增加颜色预设 2025-04-20 16:55:14 +08:00
ww-rm
7134aebb7f 增加桌面投影 2025-04-20 16:14:40 +08:00
ww-rm
abb32e9ed2 修复一些奇怪的bug 2025-04-20 16:13:50 +08:00
ww-rm
2c77e385c5 small change 2025-04-20 16:13:02 +08:00
ww-rm
ba0f5ac124 修正窗口第一次会显示的问题 2025-04-20 14:23:02 +08:00
ww-rm
c4f17e3f06 延迟运行时属性在第一次调用时初始化 2025-04-20 14:05:04 +08:00
ww-rm
b802ec252a 改成属性暴露接口 2025-04-20 13:20:22 +08:00
ww-rm
68779caab0 缩短类限定名 2025-04-20 13:19:46 +08:00
ww-rm
5d819114d0 一个没问题的版本 2025-04-20 12:49:29 +08:00
ww-rm
46b3937236 增加背景颜色设置 2025-04-20 12:43:23 +08:00
ww-rm
6803b8cf4a 修改调试输出 2025-04-20 12:42:02 +08:00
ww-rm
bd9c5a176b 增加ResolutionConverter 2025-04-20 12:41:33 +08:00
ww-rm
76c1d96c87 增加实验性功能桌面投影 2025-04-19 18:58:17 +08:00
ww-rm
304af805cb 增加scaleX和scaleY 2025-04-19 14:32:56 +08:00
ww-rm
027d3af619 增加default皮肤显示 2025-04-19 12:05:04 +08:00
ww-rm
c612c01ac7 update changelog 2025-04-19 01:48:36 +08:00
ww-rm
cd7855a877 update readme 2025-04-19 01:39:34 +08:00
ww-rm
cdd81e0bfb 修改文本描述 2025-04-19 01:35:10 +08:00
ww-rm
750a8b8aff 更新至v0.12.5 2025-04-19 01:32:29 +08:00
ww-rm
cd86155878 修复问题 2025-04-19 01:32:19 +08:00
ww-rm
16739c39d6 修复小bug 2025-04-19 00:41:40 +08:00
ww-rm
c7971a9829 update readme 2025-04-19 00:19:56 +08:00
ww-rm
44c4fc4b21 update preview 2025-04-19 00:19:47 +08:00
ww-rm
6f1c8e3320 增加槽位属性面板 2025-04-19 00:12:27 +08:00
ww-rm
8f818416ba 优化缓存字典读取 2025-04-18 23:55:08 +08:00
ww-rm
de6858ca48 增加GetSlotAttachment/SetSlotAttachment 2025-04-18 23:15:46 +08:00
ww-rm
3fd3d2a378 增加SFMLColorConverter属性描述符缓存 2025-04-18 22:37:46 +08:00
ww-rm
706c9125e6 修改皮肤设置方式为GetSkinStatus/SetSkinStatus 2025-04-18 21:56:50 +08:00
ww-rm
5f026b000c 修改皮肤设置操作为布尔型 2025-04-18 21:23:26 +08:00
ww-rm
0b0d036f08 增加SlotAttachmentNames 2025-04-18 19:31:33 +08:00
ww-rm
6b9017d535 修改名字 2025-04-18 14:50:27 +08:00
ww-rm
5eb47e33ac 修正名字 2025-04-18 14:48:08 +08:00
ww-rm
4d31335da0 修复缩放之后皮肤null引用错误 2025-04-18 11:14:32 +08:00
ww-rm
0b5e76a448 增强分辨率缓存 2025-04-18 00:09:17 +08:00
ww-rm
775268c01a 修复包围盒并集错误 2025-04-17 20:29:20 +08:00
ww-rm
b0b1c85047 更新注释和文本描述 2025-04-17 20:10:59 +08:00
ww-rm
5f08fc6695 更新至v0.12.4 2025-04-17 20:06:52 +08:00
ww-rm
2de3bdf12b 同步重命名 2025-04-17 20:06:38 +08:00
ww-rm
3a424c7dc1 update readme 2025-04-17 20:04:06 +08:00
ww-rm
c3e2b37072 update changelog 2025-04-17 20:03:46 +08:00
ww-rm
65bd11a346 增加自动分辨率 2025-04-17 20:00:15 +08:00
ww-rm
e6e7fc539f 修复Union错误 2025-04-17 19:58:14 +08:00
ww-rm
6522d415b7 增加AllowContentOverflow参数 2025-04-17 16:31:29 +08:00
ww-rm
378c66a333 small change 2025-04-17 16:30:45 +08:00
ww-rm
07204417a5 增加SetViewport 2025-04-17 16:30:27 +08:00
ww-rm
c9c909cdf9 增加padding和margin参数 2025-04-17 00:09:04 +08:00
ww-rm
a9f59a4d2f 增加对话框高度 2025-04-16 22:35:35 +08:00
ww-rm
1d2513cef5 增加padding和margin参数 2025-04-16 22:28:35 +08:00
ww-rm
febb797ae2 增加GetResolutionBounds方法 2025-04-16 21:37:09 +08:00
ww-rm
68d279a7c3 修改缩放公式 2025-04-16 21:25:26 +08:00
ww-rm
d2d8b7955c 增加GetBounds获取最大包围盒方法 2025-04-15 20:20:18 +08:00
ww-rm
2a55fd9c36 补充3.7及以下版本的多皮肤功能 2025-04-15 20:19:32 +08:00
ww-rm
695d3c0735 增加Attachments公开属性 2025-04-15 20:16:10 +08:00
ww-rm
ce95db469b 增加GetBounds 2025-04-15 20:15:50 +08:00
ww-rm
5d187cf80f 修复Path读取错误 2025-04-15 17:47:37 +08:00
ww-rm
e704ebc224 修正eventTimelines和原逻辑不一致的地方 2025-04-15 15:49:38 +08:00
ww-rm
ee36f8981c 修改GetBounds为GetCurrentBounds 2025-04-15 14:58:25 +08:00
ww-rm
09dd220abf 更改Bounds属性为GetBounds方法 2025-04-15 11:23:11 +08:00
ww-rm
15bc2dc3b8 完善文件转换功能 2025-04-14 23:52:39 +08:00
ww-rm
1deb74eca9 修正某些可能的字符大小写问题 2025-04-14 23:52:05 +08:00
ww-rm
de76ce64ab 增加输出文件夹选项 2025-04-14 23:50:46 +08:00
ww-rm
94b4ba33e6 修正curve读写 2025-04-14 21:48:23 +08:00
ww-rm
7ce8a115f4 修复流写入错误 2025-04-14 20:19:06 +08:00
ww-rm
c036a4bb45 增加v38二进制文件输出 2025-04-14 17:51:16 +08:00
ww-rm
aa62f30b05 增加报错输出 2025-04-14 17:11:56 +08:00
ww-rm
3d967c9812 修改默认打开骨骼文件后缀筛选器 2025-04-13 13:50:31 +08:00
ww-rm
e87e9efb99 补充点附件TODO 2025-04-13 00:37:29 +08:00
ww-rm
8c1f6fb4a6 update preview 2025-04-13 00:25:16 +08:00
ww-rm
df82ed8a00 更新至v0.12.3 2025-04-13 00:22:36 +08:00
ww-rm
d01e3920ba update changelog 2025-04-13 00:22:02 +08:00
ww-rm
777cd5ea3f 增加部分调试渲染功能 2025-04-13 00:19:02 +08:00
ww-rm
3b73aea5c0 增加调试骨骼 2025-04-12 20:58:56 +08:00
ww-rm
168f7a8173 修复maxFps时快进帧除0错误 2025-04-12 20:57:11 +08:00
ww-rm
04437e2de2 修改文本描述 2025-04-12 13:28:12 +08:00
ww-rm
2ec83b2e87 增加ctrl滚轮对模型缩放 2025-04-12 12:58:21 +08:00
ww-rm
90bfaa7b56 整理结构 2025-04-12 11:35:36 +08:00
ww-rm
2ae175abd0 small change 2025-04-11 13:55:19 +08:00
ww-rm
e2a84d8f88 small change 2025-04-11 00:58:25 +08:00
ww-rm
b6f9cd0c7c small change 2025-04-11 00:07:09 +08:00
ww-rm
61b7b90722 修改缩放模式 2025-04-10 10:27:09 +08:00
ww-rm
093c159753 修改布局 2025-04-10 10:21:31 +08:00
ww-rm
32d36c0757 补充遗漏参数项 2025-04-09 15:56:51 +08:00
ww-rm
94dabebf2b 修正文字说明 2025-04-09 15:34:03 +08:00
ww-rm
8e875d4f7e update changelog 2025-04-09 15:25:15 +08:00
ww-rm
86c383f2cf 默认使用libwebp_anim编码器 2025-04-09 15:24:48 +08:00
ww-rm
b404d8e79a 增加最后一帧参数 2025-04-09 15:24:31 +08:00
ww-rm
d32b480ef2 更新readme 2025-04-09 14:00:26 +08:00
ww-rm
3654825f27 补充文字说明 2025-04-09 13:52:59 +08:00
ww-rm
d7231e8a09 更新至版本v0.12.2 2025-04-09 13:43:21 +08:00
ww-rm
98161aaf2e update changelog 2025-04-09 13:40:34 +08:00
ww-rm
7a942b16bc 调整动图默认帧率 2025-04-09 13:40:11 +08:00
ww-rm
067719c69b 补充面板属性刷新 2025-04-09 13:36:34 +08:00
ww-rm
f3fce53b91 增加导出参数缓存 2025-04-09 13:19:25 +08:00
ww-rm
e35903f436 增加webp和avif动图格式 2025-04-09 13:19:17 +08:00
ww-rm
64cfe5fdd7 限定readonly 2025-04-09 01:09:57 +08:00
ww-rm
dbe586cff8 调整结构 2025-04-09 01:07:17 +08:00
ww-rm
3104733db0 补充调试参数 2025-04-08 15:00:42 +08:00
ww-rm
9d4bdd1028 标题栏增加版本号 2025-04-08 13:51:10 +08:00
ww-rm
f8030b1645 整合参数标签页 2025-04-08 13:44:30 +08:00
ww-rm
0a999ceb41 增加 SpinePropertyGrid 2025-04-08 13:21:29 +08:00
ww-rm
64bd9907cb 重构 2025-04-07 15:06:23 +08:00
ww-rm
580eaf990d 测试代码 2025-04-05 11:57:44 +08:00
ww-rm
5ab232a961 更新至v0.12.1 2025-04-05 11:56:53 +08:00
ww-rm
e596cd7ea4 update changelog 2025-04-05 11:56:13 +08:00
ww-rm
05c47a4daa 增加初始动画皮肤空位 2025-04-05 11:52:34 +08:00
ww-rm
5a8783b5f4 增加确定按钮 2025-04-05 11:18:54 +08:00
ww-rm
08bc171a72 修复分辨率调整时父容器尺寸获取错误bug 2025-04-05 10:38:17 +08:00
ww-rm
7372f5fe08 optimize 2025-04-05 10:31:30 +08:00
ww-rm
6f032bdd05 optimize 2025-04-05 10:10:04 +08:00
ww-rm
153d3603d2 optimize 2025-04-05 09:40:02 +08:00
ww-rm
95261e6907 optimize 2025-04-05 01:53:39 +08:00
ww-rm
17b344376d update readme 2025-04-05 01:39:59 +08:00
ww-rm
0ed4e44878 更新至v0.12.0 2025-04-05 01:22:14 +08:00
ww-rm
b42c1832f0 update changelog 2025-04-05 01:16:00 +08:00
ww-rm
058534ba67 修复部分资源泄漏 2025-04-05 01:14:59 +08:00
ww-rm
204dcd6498 增加3.8及以上版本多皮肤支持 2025-04-05 00:57:04 +08:00
ww-rm
2c846c0db9 补充update0 2025-04-04 20:10:29 +08:00
ww-rm
2faeb044e0 增加 readonly 限定 2025-04-04 17:36:52 +08:00
ww-rm
09c8e4f779 修复导出过程中的PMA问题 2025-04-04 17:21:30 +08:00
ww-rm
6994fa6be8 修复shader问题 2025-04-04 11:26:23 +08:00
ww-rm
cc7beb7670 增加SFMLExtension 2025-04-03 20:14:13 +08:00
ww-rm
510653732d 移除冗余引用 2025-04-03 19:46:01 +08:00
ww-rm
93e8178d67 增加部分实验性样例代码 2025-04-03 19:39:13 +08:00
ww-rm
cebc4864cc 封装原生操作 2025-04-03 18:22:55 +08:00
ww-rm
6ad0449376 修复内存泄漏 2025-04-03 18:19:12 +08:00
ww-rm
c33c977326 update changelog 2025-04-03 15:02:18 +08:00
ww-rm
f0299d365a 补充update0 2025-04-03 09:55:51 +08:00
ww-rm
6ecdca73f5 不提供时长时按所有轨道动画时长最大值导出 2025-04-03 00:30:55 +08:00
ww-rm
af6a709b2c 完善动画时间重置功能 2025-04-03 00:30:33 +08:00
ww-rm
d5c27450ef 修改pma默认值为false 2025-04-03 00:15:44 +08:00
ww-rm
d10269fb07 small change 2025-04-03 00:13:36 +08:00
ww-rm
53d987476e 增加多轨道动画编辑 2025-04-02 23:59:18 +08:00
ww-rm
8b7866d37f 增加多轨方法 2025-04-02 11:43:25 +08:00
ww-rm
bb529729b6 增加Tracks公开属性 2025-04-02 11:41:23 +08:00
ww-rm
b7735d9ba8 改成并集动画皮肤列表 2025-04-01 21:07:52 +08:00
ww-rm
ce744e2b84 update badges 2025-03-31 22:56:50 +08:00
ww-rm
631c92da3f update readme 2025-03-31 22:18:06 +08:00
ww-rm
b7063804e9 add badges 2025-03-31 22:04:31 +08:00
ww-rm
75d47c8419 修改提示文本 2025-03-31 20:55:37 +08:00
ww-rm
114fb05e80 调整布局 2025-03-31 19:28:32 +08:00
ww-rm
1fec65b37d 更新至v0.11.5 2025-03-31 17:42:54 +08:00
ww-rm
9498e8f334 update readme 2025-03-31 17:42:44 +08:00
ww-rm
83b8411929 update changelog 2025-03-31 17:34:48 +08:00
ww-rm
e9accd13b3 增加所有导出格式 2025-03-31 17:30:20 +08:00
ww-rm
9e27a19258 允许多标记 2025-03-31 14:37:47 +08:00
ww-rm
252f3a5bea 优化显示 2025-03-31 02:07:02 +08:00
ww-rm
e0626bb126 增加项数显示 2025-03-31 01:58:30 +08:00
ww-rm
7ff62c7f40 增加错误日志 2025-03-31 01:45:16 +08:00
ww-rm
4b07e02acb 增加线程安全 2025-03-31 01:44:41 +08:00
ww-rm
4654d1d9c2 优化多项操作卡顿问题 2025-03-30 20:52:22 +08:00
ww-rm
ce1f75e8a5 增加报错调试 2025-03-30 20:07:29 +08:00
ww-rm
4d9aebc758 修复预览图不显示问题 2025-03-30 20:06:13 +08:00
ww-rm
e814368ef3 移除rid 2025-03-30 19:30:58 +08:00
ww-rm
bbbb02500f 增加StringEnumConverter 2025-03-30 17:26:17 +08:00
ww-rm
404f255f14 update readme 2025-03-30 15:22:48 +08:00
ww-rm
7a15e0d38a 隐藏不可见成员 2025-03-30 13:54:17 +08:00
ww-rm
bfe669bdd9 增加FFMpegCore版本信息 2025-03-30 12:07:28 +08:00
ww-rm
c0553042fd 更新至v0.11.4 2025-03-30 11:59:52 +08:00
ww-rm
af8b02654b update readme 2025-03-30 11:59:37 +08:00
ww-rm
4779ec91d0 update changelog 2025-03-30 11:59:13 +08:00
ww-rm
14d7f4af0e 增加MP4导出格式 2025-03-30 11:56:20 +08:00
ww-rm
f9888b23dd 设置GIF默认背景颜色为纯白透明背景 2025-03-30 11:56:06 +08:00
ww-rm
411cdbb00f 设置默认颜色为纯黑透明背景 2025-03-30 11:55:52 +08:00
ww-rm
d859f07469 增加导出时输出ffmpeg参数 2025-03-29 23:48:56 +08:00
ww-rm
c111819093 增加背景颜色参数 2025-03-29 22:17:08 +08:00
ww-rm
aa8321d13c 整理代码结构 2025-03-29 21:15:34 +08:00
ww-rm
5e3bd972e5 移动GetVersion至SpineHelper 2025-03-29 17:04:26 +08:00
ww-rm
ad39a04fff 重命名SpineVersion 2025-03-29 16:59:28 +08:00
ww-rm
9a97e84296 解耦对MessageBox的依赖,提供单独的Shader初始化函数 2025-03-29 16:51:05 +08:00
ww-rm
1b7b0dcb13 解耦日志器 2025-03-29 16:30:32 +08:00
ww-rm
d365a5060b small change 2025-03-29 15:34:56 +08:00
ww-rm
b69589394a 提取ImplementationResolver实现 2025-03-29 15:12:50 +08:00
ww-rm
00f5791766 增加导出时任务栏图标显示 2025-03-28 20:53:48 +08:00
ww-rm
38cab2eda7 修复可能的预览图资源泄漏 2025-03-27 23:31:03 +08:00
ww-rm
0db4d6e4e0 small change 2025-03-27 19:45:56 +08:00
ww-rm
549712962f 去除多余组件 2025-03-27 10:11:44 +08:00
ww-rm
34b7002faf 增加背景颜色选项 2025-03-27 10:08:16 +08:00
ww-rm
0e6f47b23c 预修改适配对多轨道动画 2025-03-27 09:56:21 +08:00
ww-rm
a372a89b5e 增加update0 2025-03-27 09:09:22 +08:00
ww-rm
239847aee7 皮肤更换后使用SetSlotsToSetupPose而不是SetToSetupPose 2025-03-27 09:03:09 +08:00
ww-rm
813249c6a7 调整布局 2025-03-26 21:09:52 +08:00
ww-rm
293ab28bce 更新预览图 2025-03-26 20:49:22 +08:00
ww-rm
98e73cdec5 调整面板比例 2025-03-26 20:48:23 +08:00
ww-rm
6d34bb9d25 移除无用引用 2025-03-26 20:37:27 +08:00
ww-rm
479a5e4da9 更新至v0.11.3 2025-03-26 20:33:48 +08:00
ww-rm
4829454877 update changelog 2025-03-26 20:33:31 +08:00
ww-rm
28664f6387 增加隐藏控制 2025-03-26 20:30:55 +08:00
ww-rm
1a08a23a9c 批量添加完成自动选中最后一项 2025-03-26 20:24:27 +08:00
ww-rm
16f344ff1b 增加纹理调试 2025-03-26 19:55:43 +08:00
ww-rm
693ce0e2e8 调整属性分组和注释 2025-03-26 19:52:29 +08:00
ww-rm
e6f533ea65 优化属性分组显示顺序 2025-03-26 18:54:35 +08:00
ww-rm
fcc21d63b0 优化排列顺序 2025-03-26 18:39:30 +08:00
ww-rm
afc0ffcb67 Merge branch 'main' of github.com:ww-rm/SpineViewer 2025-03-26 18:25:56 +08:00
ww-rm
9ffb9840e1 去除限制 2025-03-26 18:25:48 +08:00
ww-rm
4766ccf1b6 互换模型和画面参数面板位置 2025-03-26 18:23:59 +08:00
ww-rm
16b75c80a3 Update README.en.md 2025-03-26 17:00:08 +08:00
ww-rm
880f063046 优化分割条可感知宽度 2025-03-26 16:20:12 +08:00
157 changed files with 50596 additions and 7735 deletions

View File

@@ -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:

View File

@@ -1,5 +1,127 @@
# 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
- 增加皮肤切换

View File

@@ -1,101 +1,111 @@
Below is the translated English version of your README:
---
# [SpineViewer](https://github.com/ww-rm/SpineViewer)
[![Build and Release](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml/badge.svg)](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
[![Build and Release](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml/badge.svg)](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
[![GitHub Release](https://img.shields.io/github/v/release/ww-rm/SpineViewer?logo=github&logoColor=959da5&label=Release&labelColor=3f4850)](https://github.com/ww-rm/SpineViewer/releases)
[![Downloads](https://img.shields.io/github/downloads/ww-rm/SpineViewer/total?logo=github&logoColor=959da5&label=Downloads&labelColor=3f4850)](https://github.com/ww-rm/SpineViewer/releases)
[中文](README.md) | [English](README.en.md)
A *WYSIWYG* Spine file viewer and exporter.
A *WYSIWYG* Spine file viewer & exporter.
![previewer](img/preview.webp)
---
## 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 highresolution 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 | Browserfriendly 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 zip 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 zip package with the `SelfContained` suffix, which can run independently.
## Supported Export Formats
- [x] Single Frame Image
- [x] Frame Sequence
- [x] Animated GIF
- [ ] MKV
- [ ] MP4
- [ ] MOV
- [ ] WebM
More formats are under development :rocket::rocket::rocket:
## Supported Spine Versions
| 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` | | | |
More versions are under development :rocket::rocket::rocket:
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 three ways to import skeleton files:
You can import Spine skeletons in three ways:
- Drag and drop or paste the skeleton file/directory into the model list.
- Open skeleton files in batch from the File menu.
- Select a single model to open from the File menu.
- Drag & drop or paste skeleton files or folders onto the model list.
- Use **File > Open** to batchopen multiple skeleton files.
- Use **File > Open Single Model** to open one at a time.
### Adjusting Preview Content
### Adjusting Content
The model list supports right-click menus and several hotkeys, and multiple models can be selected for batch adjustments of model parameters.
- Rightclick menu and keyboard shortcuts are available in the model list. You can multiselect to adjust parameters in batch.
- In the preview pane, you can also use mouse controls:
- **Leftclick & drag** to move a model; hold **Ctrl** to multiselect (synced with the list).
- **Rightclick & 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.
In addition to using the control panel for parameter settings, the preview window supports the following mouse actions:
Below the preview, playback controls let you scrub through the timeline like a basic player.
- Left-click to select and drag models. Hold the `Ctrl` key to enable multi-selection, which is synchronized with the model list on the left.
- Right-click to drag the overall view.
- Use the scroll wheel to zoom in/out.
- "Render selected only" mode, in which the preview only includes selected models and the selection can only be changed via the model list on the left.
### Exporting Content
The buttons below the preview window allow you to adjust the timeline, effectively serving as a simple player.
Exports follow the “what you see is what you get” principle—your realtime preview is exactly what gets exported.
### Exporting Preview Content
Key export options:
Export follows the "What You See Is What You Get" principle—what you see in the live preview is exactly what gets exported.
- **Render Selected Only**: includes only the selected models in both preview and export.
- **Output Folder**: if unspecified, exports go into each models 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 contents actual bounds; for animations, matches the full animation area.
There are a few key parameters for exporting:
## More
- Render Selected Only: This option not only affects the preview mode but also the export; if enabled, only the selected models will be considered, and all other models will be ignored during export.
- Output Folder: This parameter is optional in some cases. If not provided, the output will be saved in each model's own directory. Otherwise, all output files will be saved to the specified folder.
- Single Export: By default, each model is exported individually in batch mode. If "Single Export" is selected, all exported models will be rendered on a single canvas, resulting in only one output file.
### More Information
For more detailed instructions and usage, please refer to the [Wiki](https://github.com/ww-rm/SpineViewer/wiki). If you encounter any issues or bugs, please open an [Issue](https://github.com/ww-rm/SpineViewer/issues).
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).
## Acknowledgements
- [spine-runtimes](https://github.com/EsotericSoftware/spine-runtimes)
- [SFML.Net](https://github.com/SFML/SFML.Net)
- [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 others! :)*
If you find this project useful, please give it a and share it with others!
[![Stargazers over time](https://starchart.cc/ww-rm/SpineViewer.svg?variant=adaptive)](https://starchart.cc/ww-rm/SpineViewer)
[![Stargazers over time](https://starchart.cc/ww-rm/SpineViewer.svg?variant=adaptive)](https://starchart.cc/ww-rm/SpineViewer)

View File

@@ -1,6 +1,8 @@
# [SpineViewer](https://github.com/ww-rm/SpineViewer)
[![Build and Release](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml/badge.svg)](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
[![GitHub Release](https://img.shields.io/github/v/release/ww-rm/SpineViewer?logo=github&logoColor=959da5&label=Release&labelColor=3f4850)](https://github.com/ww-rm/SpineViewer/releases)
[![Downloads](https://img.shields.io/github/downloads/ww-rm/SpineViewer/total?logo=github&logoColor=959da5&label=Downloads&labelColor=3f4850)](https://github.com/ww-rm/SpineViewer/releases)
[中文](README.md) | [English](README.en.md)
@@ -8,7 +10,47 @@
![previewer](img/preview.webp)
---
## 功能
- 支持多版本 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,46 +60,19 @@
也可以下载带有 `SelfContained` 后缀的压缩包, 可以独立运行.
## 导出格式支持
- [x] 单帧画面
- [x] 帧序列
- [x] GIF 动图
- [ ] MKV
- [ ] MP4
- [ ] MOV
- [ ] WebM
更多格式正在施工 :rocket::rocket::rocket:
## Spine 版本支持
| 版本 | 查看&导出 | 格式转换 | 版本转换 |
| :---: | :---: | :---: | :---: |
| `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` | | | |
更多版本正在施工 :rocket::rocket::rocket:
导出 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 种式导入骨骼文件:
- 拖放/粘贴需要导入的骨骼文件/目录到模型列表
- 从文件菜单里批量打开骨骼文件
- 从文件菜单选择单个模型打开
### 预览内容调整
### 内容调整
模型列表支持右键菜单以及部分快捷键, 并且可以多选进行模型参数的批量调整.
@@ -65,12 +80,12 @@
- 左键可以选择和拖拽模型, 按下 `Ctrl` 键可以实现多选, 与左侧列表选择是联动的.
- 右键对整体画面进行拖动.
- 滚轮进行画面缩放.
- 滚轮进行画面缩放, 按住 `Ctrl` 可以对选中的模型进行批量缩放.
- 仅渲染选中模式, 在该模式下, 预览画面仅包含被选中的模型, 并且只能通过左侧列表改变选中状态.
预览画面下方按钮支持对画面时间进行调整, 可以当作一个简易的播放器.
### 预览内容导出
### 内容导出
导出遵循 "所见即所得" 原则, 即实时预览的画面就是你导出的画面.
@@ -79,6 +94,7 @@
- 仅渲染选中. 这个参数不仅影响预览模式, 也影响导出, 如果仅渲染选中, 那么在导出时只有被选中的模型会被考虑, 忽略其他模型.
- 输出文件夹. 这个参数某些时候可选, 当不提供时, 则将输出产物输出到每个模型各自的模型文件夹, 否则输出产物全部输出到提供的输出文件夹.
- 导出单个. 默认是每个模型独立导出, 即对模型列表进行批量操作, 如果选择仅导出单个, 那么被导出的所有模型将在同一个画面上被渲染, 输出产物只有一份.
- 自动分辨率. 该模式会忽略预览画面的分辨率和视区参数, 导出产物的分辨率与被导出内容的实际大小一致, 如果是动图或者视频则会与完整显示动画的必需大小一致.
### 更多

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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;
}

View File

@@ -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>

View File

@@ -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 () {

View File

@@ -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]; }
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="localize" value="zh-CN"/>
</appSettings>
</configuration>

View File

@@ -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);

View File

@@ -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}";
}
}
}

View 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>

View File

@@ -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="&gt;&gt;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="&gt;&gt;label_Tip.Name" xml:space="preserve">
<value>label_Tip</value>
</data>
<data name="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;toolStripMenuItem_SelectAll.Name" xml:space="preserve">
<value>toolStripMenuItem_SelectAll</value>
</data>
<data name="&gt;&gt;listBox.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;tableLayoutPanel1.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;folderBrowserDialog.Name" xml:space="preserve">
<value>folderBrowserDialog</value>
</data>
<data name="label_Tip.Text" xml:space="preserve">
<value>已添加 0 个文件</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;button_AddFile.Parent" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;flowLayoutPanel1.Type" xml:space="preserve">
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_Paste.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;button_AddFolder.Name" xml:space="preserve">
<value>button_AddFolder</value>
</data>
<data name="&gt;&gt;openFileDialog_Skel.Name" xml:space="preserve">
<value>openFileDialog_Skel</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;$this.Name" xml:space="preserve">
<value>SkelFileListBox</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;openFileDialog_Skel.Type" xml:space="preserve">
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="flowLayoutPanel1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="listBox" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,Percent,100" /&gt;&lt;/TableLayoutSettings&gt;</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>

View File

@@ -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;
}
}

View File

@@ -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)
@@ -380,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();
}
}
@@ -477,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();
@@ -485,23 +521,27 @@ 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 path = Path.Combine(Program.TempDir, $"{spine.ID}.png");
var path = Path.Combine(tempDir, $"{spine.ID}.png");
spine.Preview.Save(path);
fileDropList.Add(path);
}
@@ -544,4 +584,9 @@ namespace SpineViewer.Controls
listView.View = View.Details;
}
}
public class DefaultSpineConfig
{
}
}

View 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>

View File

@@ -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="&gt;&gt;imageList_LargeIcon.Name" xml:space="preserve">
<value>imageList_LargeIcon</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;toolStripMenuItem_MoveDown.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;toolStripSeparator2.Name" xml:space="preserve">
<value>toolStripSeparator2</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;columnHeader_Name.Type" xml:space="preserve">
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;toolStripMenuItem_Add.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;listView.Type" xml:space="preserve">
<value>System.Windows.Forms.ListView, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;statusStrip.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_Remove.Name" xml:space="preserve">
<value>toolStripMenuItem_Remove</value>
</data>
<data name="&gt;&gt;statusStrip.Type" xml:space="preserve">
<value>System.Windows.Forms.StatusStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="listView" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="statusStrip" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="Percent,100,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;timer_SelectedIndexChangedDebounce.Type" xml:space="preserve">
<value>System.Windows.Forms.Timer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableLayoutPanel.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;toolStripMenuItem_Insert.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;toolStripMenuItem_ListView.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;listView.Parent" xml:space="preserve">
<value>tableLayoutPanel</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;toolStripSeparator1.Name" xml:space="preserve">
<value>toolStripSeparator1</value>
</data>
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
<value>移除</value>
</data>
<data name="&gt;&gt;tableLayoutPanel.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_BatchAdd.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_RemoveAll.Name" xml:space="preserve">
<value>toolStripMenuItem_RemoveAll</value>
</data>
<data name="toolStripMenuItem_MoveTop.Text" xml:space="preserve">
<value>置顶</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_DetailsView.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;listView.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;toolStripMenuItem_CopyPreview.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;toolStripMenuItem_SelectAll.Name" xml:space="preserve">
<value>toolStripMenuItem_SelectAll</value>
</data>
<data name="&gt;&gt;toolStripSeparator3.Name" xml:space="preserve">
<value>toolStripSeparator3</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;toolStripMenuItem_ChangeView.Name" xml:space="preserve">
<value>toolStripMenuItem_ChangeView</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;contextMenuStrip.Name" xml:space="preserve">
<value>contextMenuStrip</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;toolStripMenuItem_ChangeView.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_SelectAll.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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>

View 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;
}
}

View 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; }
}
}

View 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>

View 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="&gt;&gt;button_ForwardFast.Name" xml:space="preserve">
<value>button_ForwardFast</value>
</data>
<data name="&gt;&gt;button_ForwardFast.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;wallpaperForm.Name" xml:space="preserve">
<value>wallpaperForm</value>
</data>
<data name="button_Restart.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel_RenderContainer.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel_Render.Name" xml:space="preserve">
<value>panel_Render</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>SpinePreviewPanel</value>
</data>
<data name="&gt;&gt;button_Stop.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;button_ForwardFast.Parent" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel_RenderContainer.Parent" xml:space="preserve">
<value>panel_ViewContainer</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="wallpaperForm.ToolTip" xml:space="preserve">
<value />
</data>
<data name="&gt;&gt;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="&gt;&gt;button_Stop.Name" xml:space="preserve">
<value>button_Stop</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;button_FullScreen.Parent" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="flowLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="&gt;&gt;imageList.Name" xml:space="preserve">
<value>imageList</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;$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="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="flowLayoutPanel1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="panel_ViewContainer" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="Percent,100,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="button_FullScreen.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
<value>GrowAndShrink</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tableLayoutPanel1.Name" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel_Render.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;button_Stop.Parent" xml:space="preserve">
<value>flowLayoutPanel1</value>
</data>
<data name="&gt;&gt;button_FullScreen.Name" xml:space="preserve">
<value>button_FullScreen</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;flowLayoutPanel1.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="button_Start.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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>

View File

@@ -1,223 +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()
{
components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpinePreviewer));
panel = new Panel();
tableLayoutPanel1 = new TableLayoutPanel();
panel_Container = new Panel();
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();
toolTip = new ToolTip(components);
tableLayoutPanel1.SuspendLayout();
panel_Container.SuspendLayout();
flowLayoutPanel1.SuspendLayout();
SuspendLayout();
//
// panel
//
panel.BackColor = SystemColors.ControlDarkDark;
panel.Location = new Point(157, 136);
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;
//
// tableLayoutPanel1
//
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(panel_Container, 0, 0);
tableLayoutPanel1.Controls.Add(flowLayoutPanel1, 0, 1);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 0);
tableLayoutPanel1.Margin = new Padding(0);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 2;
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(641, 636);
tableLayoutPanel1.TabIndex = 2;
//
// panel_Container
//
panel_Container.BackColor = SystemColors.ControlDark;
panel_Container.Controls.Add(panel);
panel_Container.Dock = DockStyle.Fill;
panel_Container.Location = new Point(0, 0);
panel_Container.Margin = new Padding(0);
panel_Container.Name = "panel_Container";
panel_Container.Size = new Size(641, 594);
panel_Container.TabIndex = 0;
//
// flowLayoutPanel1
//
flowLayoutPanel1.Anchor = AnchorStyles.None;
flowLayoutPanel1.AutoSize = true;
flowLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
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.Location = new Point(138, 594);
flowLayoutPanel1.Margin = new Padding(0);
flowLayoutPanel1.Name = "flowLayoutPanel1";
flowLayoutPanel1.Size = new Size(365, 42);
flowLayoutPanel1.TabIndex = 1;
//
// button_Stop
//
button_Stop.AutoSize = true;
button_Stop.AutoSizeMode = AutoSizeMode.GrowAndShrink;
button_Stop.ImageKey = "stop";
button_Stop.ImageList = imageList;
button_Stop.Location = new Point(3, 3);
button_Stop.Name = "button_Stop";
button_Stop.Padding = new Padding(15, 3, 15, 3);
button_Stop.Size = new Size(67, 36);
button_Stop.TabIndex = 0;
toolTip.SetToolTip(button_Stop, "停止播放并重置时间到初始");
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, "stop");
imageList.Images.SetKeyName(1, "restart");
imageList.Images.SetKeyName(2, "start");
imageList.Images.SetKeyName(3, "pause");
imageList.Images.SetKeyName(4, "forward-step");
imageList.Images.SetKeyName(5, "forward-fast");
//
// button_Restart
//
button_Restart.AutoSize = true;
button_Restart.AutoSizeMode = AutoSizeMode.GrowAndShrink;
button_Restart.ImageKey = "restart";
button_Restart.ImageList = imageList;
button_Restart.Location = new Point(76, 3);
button_Restart.Name = "button_Restart";
button_Restart.Padding = new Padding(15, 3, 15, 3);
button_Restart.Size = new Size(67, 36);
button_Restart.TabIndex = 1;
toolTip.SetToolTip(button_Restart, "从头开始播放");
button_Restart.UseVisualStyleBackColor = true;
button_Restart.Click += button_Restart_Click;
//
// button_Start
//
button_Start.AutoSize = true;
button_Start.AutoSizeMode = AutoSizeMode.GrowAndShrink;
button_Start.BackgroundImageLayout = ImageLayout.Center;
button_Start.ImageKey = "pause";
button_Start.ImageList = imageList;
button_Start.Location = new Point(149, 3);
button_Start.Name = "button_Start";
button_Start.Padding = new Padding(15, 3, 15, 3);
button_Start.Size = new Size(67, 36);
button_Start.TabIndex = 2;
toolTip.SetToolTip(button_Start, "开始/暂停");
button_Start.UseVisualStyleBackColor = true;
button_Start.Click += button_Start_Click;
//
// button_ForwardStep
//
button_ForwardStep.AutoSize = true;
button_ForwardStep.AutoSizeMode = AutoSizeMode.GrowAndShrink;
button_ForwardStep.ImageKey = "forward-step";
button_ForwardStep.ImageList = imageList;
button_ForwardStep.Location = new Point(222, 3);
button_ForwardStep.Name = "button_ForwardStep";
button_ForwardStep.Padding = new Padding(15, 3, 15, 3);
button_ForwardStep.Size = new Size(67, 36);
button_ForwardStep.TabIndex = 3;
toolTip.SetToolTip(button_ForwardStep, "快进 1 帧");
button_ForwardStep.UseVisualStyleBackColor = true;
button_ForwardStep.Click += button_ForwardStep_Click;
//
// button_ForwardFast
//
button_ForwardFast.AutoSize = true;
button_ForwardFast.AutoSizeMode = AutoSizeMode.GrowAndShrink;
button_ForwardFast.ImageKey = "forward-fast";
button_ForwardFast.ImageList = imageList;
button_ForwardFast.Location = new Point(295, 3);
button_ForwardFast.Name = "button_ForwardFast";
button_ForwardFast.Padding = new Padding(15, 3, 15, 3);
button_ForwardFast.Size = new Size(67, 36);
button_ForwardFast.TabIndex = 4;
toolTip.SetToolTip(button_ForwardFast, "快进 10 帧");
button_ForwardFast.UseVisualStyleBackColor = true;
button_ForwardFast.Click += button_ForwardFast_Click;
//
// SpinePreviewer
//
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
Controls.Add(tableLayoutPanel1);
Name = "SpinePreviewer";
Size = new Size(641, 636);
SizeChanged += SpinePreviewer_SizeChanged;
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
panel_Container.ResumeLayout(false);
flowLayoutPanel1.ResumeLayout(false);
flowLayoutPanel1.PerformLayout();
ResumeLayout(false);
}
#endregion
private Panel panel;
private TableLayoutPanel tableLayoutPanel1;
private Panel panel_Container;
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;
}
}

View File

@@ -1,647 +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;
namespace SpineViewer.Controls
{
public partial class SpinePreviewer : UserControl
{
/// <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;
#region
/// <summary>
/// 画面缩放最大值
/// </summary>
public const float ZOOM_MAX = 1000f;
/// <summary>
/// 画面缩放最小值
/// </summary>
public const float ZOOM_MIN = 0.001f;
/// <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>
/// 分辨率
/// </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;
/// <summary>
/// 获取 View
/// </summary>
public SFML.Graphics.View GetView() => RenderWindow.GetView();
#endregion
public SpinePreviewer()
{
InitializeComponent();
RenderWindow = new(panel.Handle);
RenderWindow.SetActive(false);
// 设置默认参数
Resolution = new(2048, 2048);
Center = new(0, 0);
FlipY = true;
MaxFps = 30;
}
#region 线
/// <summary>
/// 渲染窗口
/// </summary>
private readonly SFML.Graphics.RenderWindow RenderWindow;
/// <summary>
/// 渲染任务
/// </summary>
private Task? task = null;
private CancellationTokenSource? cancelToken = null;
/// <summary>
/// 开始渲染
/// </summary>
public void StartRender()
{
if (task is not null)
return;
cancelToken = new();
task = Task.Run(RenderTask, cancelToken.Token);
IsUpdating = true;
}
/// <summary>
/// 停止渲染
/// </summary>
public void StopRender()
{
IsUpdating = false;
if (task is null || cancelToken is null)
return;
cancelToken.Cancel();
task.Wait();
cancelToken = null;
task = null;
}
#endregion
#region
/// <summary>
/// 是否更新画面
/// </summary>
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>
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.System.Clock Clock = new();
/// <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];
// 停止更新的时候只是时间不前进, 但是坐标变换还是要更新, 否则无法移动对象
if (!IsUpdating) delta = 0;
// 加上要快进的量
lock (_forwardDeltaLock)
{
delta += forwardDelta;
forwardDelta = 0;
}
spine.Update(delta);
if (RenderSelectedOnly && !spine.IsSelected)
continue;
spine.IsDebug = true;
RenderWindow.Draw(spine);
spine.IsDebug = false;
}
}
}
RenderWindow.Display();
}
}
finally
{
RenderWindow.SetActive(false);
}
}
#endregion
/// <summary>
/// 画面拖放对象世界坐标源点
/// </summary>
private SFML.System.Vector2f? draggingSrc = null;
private void SpinePreviewer_SizeChanged(object sender, EventArgs e)
{
if (RenderWindow is null)
return;
float parentX = panel.Parent.Width;
float parentY = panel.Parent.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();
}
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.CurrentAnimation = spine.CurrentAnimation;
}
}
}
private void button_Restart_Click(object sender, EventArgs e)
{
if (SpineListView is not null)
{
lock (SpineListView.Spines)
{
foreach (var spine in SpineListView.Spines)
spine.CurrentAnimation = spine.CurrentAnimation;
}
}
IsUpdating = true;
}
private void button_Start_Click(object sender, EventArgs e)
{
IsUpdating = !IsUpdating;
}
private void button_ForwardStep_Click(object sender, EventArgs e)
{
lock (_forwardDeltaLock)
{
forwardDelta += 1f / maxFps;
}
}
private void button_ForwardFast_Click(object sender, EventArgs e)
{
lock (_forwardDeltaLock)
{
forwardDelta += 10f / maxFps;
}
}
//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);
}
}

View File

@@ -1,326 +0,0 @@
<?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>
<metadata name="imageList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="imageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAHi0AAAJNU0Z0AUkBTAIBAQYB
AAFwAQABcAEAAR8BAAEYAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABfAMAATADAAEBAQABIAYAAV0q
AAQCAy0BRQNbAc0DXQHoA1kBxgMyAU8DDwEUBAIYAAMOARIDQwF3A10BzwNbAc0DLQFFBAIYAANWAbID
XQHoA1wB1gNDAXcDFgEeBAIYAAMKAQ0DSQGFA14B4wNfAeUDUQGeAyQBNAMJAQsEARgAAwsBDgM7AWQD
XgHSA1YBsv8AEQAEAgMxAUwDYQHhAwAB/wMuAfkDYAHbA0QBewMeASoDBgEIFAADGAEhA1cBwgMhAfsD
YQHhAzEBTAQCGAADWQHDAwAB/wMhAfwDXAHrA0gBhAMWAR4YAAMLAQ4DTQGSAysB+QMPAf4DUAHyA1gB
ugM3AVoDEQEWAwIBAxQAAxcBHwNJAYYDXAHrA1kBw/8AEQAEAgMxAUwDYQHhAwAB/wMAAf8DHgH9A2AB
4ANQAZoDLgFGAxEBFgMGAQcEAQgAAxoBJANbAc0DAAH/A2EB4QMxAUwEAhgAA1kBwwMAAf8DAAH/AwAB
/wNbAdADPgFrAw8BEwMCAQMQAAMLAQ4DTQGSAysB+QMAAf8DAAH/AzkB9gNcAcsDRAF5Ax4BKgMGAQcM
AAQBAxgBIQNKAYsDWwHsA1kBw/8AEQAEAgMxAUwDYQHhAwAB/wMuAfkDXAHnA0MB9QNWAe4DWQG7A0MB
dwMoATsDDwEUBAEEAAMaASQDWwHNAwAB/wNhAeEDMQFMBAIYAANZAcMDIAH8A1AB8ANDAfUDLgH5A10B
zgNDAXcDGgEjAwIBAwwAAwsBDgNNAZIDKwH5AwEB/wMkAfoDOgH4Ay4B+QNdAeMDTgGYAyQBNQMGAQgE
AQQABAEDGAEhA0oBiwNbAewDWQHD/wARAAQCAzEBTANhAeEDAAH/A1wB2QM7AWMDWQG7Az0B9wM5AfgD
XAHnA1sBxQNBAXMDEwEZAwIBAwMaASQDWwHNAwAB/wNhAeEDMQFMBAIYAANZAcMDXAHrA1ABmgNVAbED
TQHzAyEB+wNbAeQDSwGPAxsBJQMDAQQIAAMLAQ4DTQGSAysB+QMfAf0DXAHZA1oBxwNDAfUDDwH+A1wB
6wNSAaMDJQE3AwMBBAQABAEDGAEhA0oBiwNbAewDWQHD/wARAAQCAzEBTANhAeEDAAH/A1sBzQMaASQD
FgEdA1UBrwMAAf8DAAH/AwAB/wMAAf8DVQGvAxYBHQMaASQDWwHNAwAB/wNhAeEDMQFMBAIYAANZAcMD
WwHkAzsBZQMHAQkDSQGGAyEB+wMAAf8DAAH/A1kBwQMdASkIAAMLAQ4DTQGSAysB+QMrAfkDTQGSAzkE
XgHiAwAB/wMAAf8DXQHjAzYBWAMFAQYEAAQBAxgBIQNKAYsDWwHsA1kBw/8AEQAEAgMxAUwDYQHhAwAB
/wNbAc0DGgEkAwIBAwMTARoDRgF/A1sB3gMhAfsDDwH+AzkB+ANZAbsDOwFjA1wB2QMAAf8DYQHhAzEB
TAQCGAADWQHDA1sB5AM7AWUDBwQJAQwDOgFhA18B1QNCAfUDLgH5A1sBygMyAU8DDwEUAw0BEQNNAZID
KwH5AysB+QNNAZIDEQEWAy0BRANaAb8DUgHvAyEB+wNdAdwDPwFuAxYBHgMEAQUDGAEhA0oBiwNbAewD
WQHD/wARAAQCAzEBTANhAeEDAAH/A1sBzQMaASQEAAQCAxMBGgM9AWcDWQHAA1IB7wMPAf4DPQH3A1wB
5wMuAfkDAAH/A2EB4QMxAUwEAhgAA1kBwwNbAeQDOwFlAwcBCQQAAwsBDgMxAU0DWAG9AzkB9gMuAfkD
YAHbA0QBeAMhAS8DTgGVAysB+QMrAfkDTQGSAwsBDgMGAQgDIAEuA00BkgNdAdwDQwH1A1oB6QNOAZYD
KAE8AyABLQNLAY0DWwHsA1kBw/8AEQAEAgMxAUwDYQHhAwAB/wNbAc0DGgEkCAAEAgMMARADLwFJA1IB
owNbAeQDPQH3Aw8B/gMAAf8DAAH/A2EB4QMxAUwEAhgAA1kBwwNbAeQDOwFlAwcBCQgAAxABFQM/AW0D
XAHWAyQB+gMeAf0DXAHWA0QBeQNUAasDIQH7AysB+QNNAZIDCwEOBAADAwEEAxsBJgNBAXMDWgHEA0UB
9ANWAe4DVQG0A0QBegNRAaIDVgHuA1kBw/8AEQAEAgMxAUwDYQHhAwAB/wNbAc0DGgEkEAADCAEKAyMB
MwNEAXkDVwG8A18B5QMkAfoDAAH/A2EB4QMxAUwEAhgAA1kBwwNbAeQDOwFlAwcBCQgAAwMBBAMaASQD
QgF0A14B0gMhAfsDOQH2A10B0QNgAeADHgH9AysB+QNNAZIDCwEOCAADAgEDAxIBFwM1AVUDWAG6A1UB
8QM5AfYDWwHeA2AB2wM5AfgDWQHD/wARAAQCAzEBTANhAeEDAAH/A1sBzQMaASQUAAMCAQMDDgESAyMB
MgM9AWgDXgHdAwAB/wNhAeEDMQFMBAIYAANZAcMDWwHkAzsBZQMHAQkMAAMCAQMDDwETAzQBUwNdAdED
OQH4Ax8B/AMfAf0DAAH/AysB+QNNAZIDCwEODAAEAQMJAQwDIwEzA1UBrgMgAf0DHgH9Ax8B/AMPAf4D
WQHD/wARAAQCAzEBTANhAeEDAAH/A1sBzQMaASQgAAMaASQDWwHNAwAB/wNhAeEDMQFMBAIYAANZAcMD
WwHkAzsBZQMHAQkYAAMPARQDVwG5AwAB/wMAAf8DAAH/AysB+QNNAZIDCwEOGAADRwGAA1wB7QMAAf8D
AAH/AwAB/wNZAcP/ABEABAIDMQFMA2EB4QMAAf8DWwHNAxoBJBQABAIDBwEJAxYBHQM1AVUDXAHZAwAB
/wNhAeEDMQFMBAIYAANZAcMDWwHkAzsBZQMHAQkMAAQBAw0BEQM0AVMDXQHRAy4B+QMQAf4DDwH+AwAB
/wMrAfkDTQGSAwsBDgwABAEDCQELAx4BKwNTAakDIAH9Ax4B/QMfAfwDDwH+A1kBw/8AEQAEAgMxAUwD
YQHhAwAB/wNbAc0DGgEkEAADBwEJAxsBJgM0AVMDTQGSA14B3QMuAfkDAAH/A2EB4QMxAUwEAhgAA1kB
wwNbAeQDOwFlAwcBCQgABAIDEAEVAzkBXgNbAc0DIQH7AyEB+wNcAecDVgHuAw8B/gMrAfkDTQGSAwsB
DggAAwIBAwMSARcDNQFVA1gBuANVAfEDOQH2A1sB3gNgAdsDOQH4A1kBw/8AEQAEAgMxAUwDYQHhAwAB
/wNbAc0DGgEkCAAEAgMMARADLgFGA00BkgNcAcgDXAHrAx4B/QMAAf8DAAH/A2EB4QMxAUwEAhgAA1kB
wwNbAeQDOwFlAwcBCQgAAwkBDAMxAU4DWAG3A00B8wMeAf0DXgHdA04BlgNZAb4DHwH8AysB+QNNAZID
CwEOBAADAwEEAxsBJgNBAXMDWgHEA0UB9ANWAe4DVQG0A0QBegNRAaIDVgHuA1kBw/8AEQAEAgMxAUwD
YQHhAwAB/wNbAc0DGgEkBAAEAgMTARoDPQFnA1oBvwNcAesDJAH6AzoB9gNcAecDLgH5AwAB/wNhAeED
MQFMBAIYAANZAcMDWwHkAzsBZQMHAQkEAAMLAQ4DLgFHA1UBrQNSAe8DOgH4A2AB2wNEAXoDJAE1A04B
mAMjAfoDKwH5A00BkgMLAQ4DBgEIAyABLgNNAZIDXQHcA0MB9QNaAekDTgGWAygBPAMgAS0DSwGNA1sB
7ANZAcP/ABEABAIDMQFMA2EB4QMAAf8DWwHNAxoBJAMCAQMDEwEaA0YBfwNbAd4DIQH7Aw8B/gM5AfgD
WQG7AzsBYwNcAdkDAAH/A2EB4QMxAUwEAhgAA1kBwwNbAeQDOwFlAwcECQEMAzoBYQNdAdQDRQH0Ay4B
+QNbAcoDMgFPAw8BFAMNAREDTQGSAysB+QMrAfkDTQGSAxEBFgMtAUQDWgG/A1IB7wMgAfwDYAHgA0AB
cQMXAR8DBAEFAxgBIQNKAYsDWwHsA1kBw/8AEQAEAgMxAUwDYQHhAwAB/wNbAc0DGgEkAxYBHQNVAa8D
AAH/AwAB/wMAAf8DAAH/A1UBrwMWAR0DGgEkA1sBzQMAAf8DYQHhAzEBTAQCGAADWQHDA1sB5AM7AWUD
BwEJA0kBhgMhAfsDAAH/AwAB/wNZAcEDHQEpCAADCwEOA00BkgMrAfkDKwH5A00BkgM5BF4B4gMAAf8D
AAH/A1gB7QNKAYsDGAEgCAEDGAEhA0oBiwNbAewDWQHD/wARAAQCAzEBTANhAeEDAAH/A1wB2QM7AWMD
WQG7Az0B9wMgAfwDRQH0A1wB2QNGAX4DEwEaAwIBAwMaASQDWwHNAwAB/wNhAeEDMQFMBAIYAANZAcMD
XAHrA1ABmgNVAbEDTQHzAyEB+wNfAeUDSwGPAxsBJQMDAQQIAAMLAQ4DTQGSAysB+QMhAfsDVgGzA0wB
jgNcAesDDwH+A1AB8ANXAbkDLgFHAwYBCAQABAEDGAEhA0oBiwNbAewDWQHD/wARAAQCAzEBTANhAeED
AAH/Ay4B+QNcAecDQwH1A1QB8QNbAdMDUQGkAzgBWwMTARkEAgQAAxoBJANbAc0DAAH/A2EB4QMxAUwE
AhgAA1kBwwMgAfwDUAHwA0MB9QMfAf0DXgHXA0YBfgMaASQDAgEDDAADCwEOA00BkgMrAfkDDwH+A00B
8wNWAe4DPQH3A10B4wNOAZgDJwE5AwgBCgQBBAAEAQMYASEDSgGLA1sB7ANZAcP/ABEABAIDMQFMA2EB
4QMAAf8DAAH/Ax4B/QNhAeEDUgGjAzsBYwMhAS8DCgENBAIIAAMaASQDWwHNAwAB/wNhAeEDMQFMBAIY
AANZAcMDAAH/AwAB/wMAAf8DXQHoA0oBiwMWAR0DBAEFEAADCwEOA00BkgMrAfkDAAH/AwAB/wM5AfYD
XAHLA0QBeQMeASoDBgEHDAAEAQMYASEDSgGLA1sB7ANZAcP/ABEABAIDMQFMA2EB4QMAAf8DLgH5A2AB
2wNFAXwDIQEwAwwBEAMDAQQQAAMaASMDXAHIAx8B/QNhAeEDMQFMBAIYAANZAcMDAAH/AyEB/ANcAesD
TgGXAyMBMwQCFAADCwEOA00BkgMrAfkDDwH+A1AB8gNYAboDNwFaAxEBFgMCAQMUAAMXAR8DSQGGA1wB
6wNZAcP/ABEABAIDLQFFA14B0gNQAfIDXQHJAzIBTwMQARUDAgEDGAADEwEaA1ABnwNbAeQDWwHQAy0B
RQQCGAADVQG0A1cB7gNfAdoDRAF4AxgBIAMDAQQYAAMKAQ0DSQGGA10B6ANaAekDUAGfAyQBNAMJAQsE
ARgAAwsBDgM7AWUDWwHTA1YBsv8AFQADAwEEAycBOgM/AW0DFAEbKAADDwETAzEBTgMdASkDAgEDHAAD
DgESAzEBTQMjATMDBAEFJAADBgEHAygBPAMoATwDBgEHJAAEAQMHAQkDCwEOAwIBA/8ABQADAgEDAw8B
FANJAYgDXwHlA10B6ANdAegDXQHoA10B6ANdAegDXQHoA10B6ANdAegDXQHoA10B6ANdAegDXQHoA10B
6ANdAegDXQHoA10B6ANdAegDXQHoA1sB5ANGAX4DBQEGBAEoAAMCAQMDDQERAx8BLAMtAUYDVwG5A10B
6ANdAegDXQHoA10B6ANdAegDXQHoA18B4wNZAb4DMgFPAw8BEwMCAQMwAAMTARkDRgF+A10B6ANdAegD
WQHBAzkBXgMmATgDDwEUBAJcAAM5AV8DXgHiA1wB5wNdAegDXQHoA10B6ANdAegDXQHcAzwBZgMGAQgD
BgEIAzwBZgNdAdwDXQHoA10B6ANdAegDXQHoA10B3ANQAZ0DJQE2IAADDAEQAzwBZgNdAc8DHgH9AyQB
+gNSAe8DWAHtA1gB7QNYAe0DWAHtA1gB7QNYAe0DWAHtA1gB7QNYAe0DWAHtA1gB7QNYAe0DWAHtA1gB
7QNSAe8DJAH6AyAB/ANWAbUDKwFCAwgBCiQABAIDGAEhA0ABcANaAb8DXQHfA1oB7QNSAe8DWwHsA14B
5gNfAeUDWAHqA1gB7QNQAfADOgH2A10B0QNDAXcDHgErAwYBBywAAz0BaQNbAd4DAQH/Ay4B+QNcAewD
WwHkA14B1wNEAXsDHgEqAwYBCFgAAz8BbAMfAf0DOQH4A1IB7wNYAe0DVgHuAyQB+gM5AfYDTwGbAx4B
KwMgAS0DUAGdAzkB9gMkAfoDVgHuA1gB7QNSAe8DPQH3A1AB8gM7AWUgAAMTARkDUAGcAz0B9wM6AfYD
XQHMA0sBjQNGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYAD
RgGAA0sBjwNcAdkDHgH9A1QB8QNOAZQDEgEYJAADBQEGAzEBTgNbAdADUAHyA14B4gNVAa4DSgGKA0YB
fwNDAXcDQwF2A0UBfANGAYADTwGbA14B3QNdAegDXwHaA04BlgMoATwDCQEMKAADRwGDAzkB+AMgAfwD
WwHTA1MBpgNcAdkDLgH5A2AB4ANQAZoDLQFEAwsBDlQAAz8BbAMgAfwDWwHTA0wBjgNGAYADSgGKA10B
3AMfAf0DXgHdAzoBYAM6AWIDXQHfAx4B/QNdAdwDSgGKA0YBgANMAY4DWwHTAyAB/AM/AWwgAAMUARsD
UgGlAx0B/QNbAdADPwFsAxgBIQMOARIDDgESAw4BEgMOARIDDgESAw4BEgMOARIDDgESAw4BEgMOARID
DgESAw4BEgMOARIDDgESAyABLgNXAbkDHgH9Ax0B/QNSAaUDFAEbJAADBQEGAzEBTQNaAccDXAHIA0AB
bwMlATcDEwEaAw4BEgMNAREDDAEQAw4BEgMOARIDHQEoAzoBYANLAY8DWwHYA14B5gNWAbYDMQFNAwYB
CCQAA0kBhgMhAfsDLgH5A1UBrgMqAUADPwFtA10B0QNDAfUDVgHuA1gBtwM2AVcDFgEdAwwBEAQCSAAD
PwFsAy4B+QNVAa4DIAEtAw4BEgMbASUDWQG+AwAB/wNYAe0DPwFtAz8BbQNYAe0DAAH/A1kBvgMbASUD
DgESAyABLQNVAa4DLgH5Az8BbCAAAxQBGwNSAaUDHQH9A1YBtgMoATwDCAEKOAADFgEeA1YBswMeAf0D
HQH9A1IBpQMUARskAAQBAw8BFAMjATMDIQEwAwsBDgMDAQQEARQABAIDBwEJAx4BKgNLAYwDXQHfAz0B
9wNTAakDKAE7JAADSQGGAyEB+wMuAfkDUwGnAxYBHgMMARADKgFAA1gBugNOAfMDRgH0A2AB2wNXAbwD
QgF0AxMBGQMCAQNEAAM/AWwDLgH5A1MBpwMVARwEAAMPARQDVwG5AwAB/wNYAe0DPwFtAz8BbQNYAe0D
AAH/A1cBuQMPARQEAAMVARwDUwGnAy4B+QM/AWwgAAMUARsDUgGlAx0B/QNVAbQDJgE4AwcBCTgAAxYB
HgNWAbMDHgH9Ax0B/QNSAaUDFAEbYAADFQEcA1MBpwMuAfkDIQH7A0kBhiQAA0kBhgMhAfsDLgH5A1MB
pwMVARwIAAMPARMDQwF2A1wB2QMfAf0DAAH/AwAB/wNVAa8DFgEdRAADPwFsAy4B+QNTAacDFQEcBAAD
DwEUA1cBuQMAAf8DWAHtAz8BbQM/AW0DWAHtAwAB/wNXAbkDDwEUBAADFQEcA1MBpwMuAfkDPwFsIAAD
FAEbA1IBpQMdAf0DVQG0AyYBOAMHAQk4AAMWAR4DVgGzAx4B/QMdAf0DUgGlAxQBG2AAAwIBAwMeASoD
VQG0Az0B9wNSAaADGwElAwUBBhwAA0kBhgMhAfsDLgH5A1MBpwMVARwIAAQCAwkBCwMYASADRAF6A2AB
2wM7AfcDPQH3A1kBuwMqAUADDgESAwUBBgQCNAADPwFsAy4B+QNTAacDFQEcBAADDwEUA1cBuQMAAf8D
WAHtAz8BbQM/AW0DWAHtAwAB/wNXAbkDDwEUBAADFQEcA1MBpwMuAfkDPwFsIAADFAEbA1IBpQMdAf0D
VQG0AyYBOAMHAQk4AAMWAR4DVgGzAx4B/QMdAf0DUgGlAxQBG2QAAw8BEwNAAW8DXQHUA1MB7wNMAZED
EgEYHAADSQGGAyEB+wMuAfkDUwGnAxUBHBAABAIDDQERAzYBVwNYAbcDWwHsA1UB8QNdAdEDRAF5AzMB
UAMbASYDBgEHMAADPwFsAy4B+QNTAacDFQEcBAADDwEUA1cBuQMAAf8DWAHtAz8BbQM/AW0DWAHtAwAB
/wNXAbkDDwEUBAADFQEcA1MBpwMuAfkDPwFsIAADFAEbA1IBpQMdAf0DVQG0AyYBOAMHAQk4AAMWAR4D
VgGzAx4B/QMdAf0DUgGlAxQBG2QAAwIBAwMPARMDUQGeAx0B/QNSAaUDFAEbHAADSQGGAyEB+wMuAfkD
UwGnAxUBHBgAAwsBDgMtAUQDSwGPA1sBxQNhAeEDYQHhA1sBzQNMAZADKAE7AwkBDCwAAz8BbAMuAfkD
UwGnAxUBHAQAAw8BFANXAbkDAAH/A1gB7QM/AW0DPwFtA1gB7QMAAf8DVwG5Aw8BFAQAAxUBHANTAacD
LgH5Az8BbCAAAxQBGwNSAaUDHQH9A1UBtAMmATgDBwEJOAADFgEeA1YBswMeAf0DHQH9A1IBpQMUARts
AANNAZMDHQH9A1IBpQMUARscAANJAYYDIQH7Ay4B+QNTAacDFQEcHAADBgEIAxkBIgMvAUkDQAFxA10B
zANNAfMDWgHpA1YBtgMtAUQsAAM/AWwDLgH5A1MBpwMVARwEAAMPARQDVwG5AwAB/wNYAe0DPwFtAz8B
bQNYAe0DAAH/A1cBuQMPARQEAAMVARwDUwGnAy4B+QM/AWwgAAMUARsDUgGlAx0B/QNVAbQDJgE4AwcB
CTgAAxYBHgNWAbMDHgH9Ax0B/QNSAaUDFAEbbAADTQGTAx0B/QNSAaUDFAEbHAADSQGGAyEB+wMuAfkD
UwGnAxUBHCAABAIDBAEFAwsBDgMwAUwDWQHBAzoB9gMsAfkDQQFyAwYBCCgAAz8BbAMuAfkDUwGnAxUB
HAQAAw8BFANXAbkDAAH/A1gB7QM/AW0DPwFtA1gB7QMAAf8DVwG5Aw8BFAQAAxUBHANTAacDLgH5Az8B
bCAAAxQBGwNSAaUDHQH9A1UBtAMmATgDBwEJOAADFgEeA1YBswMeAf0DHQH9A1IBpQMUARtsAANNAZMD
HQH9A1IBpQMUARscAANJAYYDIQH7Ay4B+QNTAacDFQEcMAADFQEcA1MBpwMuAfkDWwHTAzoBYSgAAz8B
bAMuAfkDUwGnAxUBHAQAAw8BFANXAbkDAAH/A1gB7QM/AW0DPwFtA1gB7QMAAf8DVwG5Aw8BFAQAAxUB
HANTAacDLgH5Az8BbCAAAxQBGwNSAaUDHQH9A1UBtAMmATgDBwEJOAADFgEeA1YBswMeAf0DHQH9A1IB
pQMUARsQAAQBAwQBBQMLAQ4DDwETAw8BEwMPARMDDwETAw8BEwMNAREDCQEMAwMBBAQBLAADTQGTAx0B
/QNSAaUDFAEbHAADSQGGAyEB+wMuAfkDUwGnAxUBHCAABAEDAgEDAwsBDgMwAUwDWQHBAzoB9gMsAfkD
QQFyAwYBCCgAAz8BbAMuAfkDUwGnAxUBHAQAAw8BFANXAbkDAAH/A1gB7QM/AW0DPwFtA1gB7QMAAf8D
VwG5Aw8BFAQAAxUBHANTAacDLgH5Az8BbCAAAxQBGwNSAaUDHQH9A1UBtAMmATgDBwEJOAADFgEeA1YB
swMeAf0DHQH9A1IBpQMUARsQAAMGAQgDJAE1Az4BawNGAX0DRgF+A0YBfgNGAX4DRgF+A0QBewM9AWkD
JAE0AwkBDCwAA00BkwMdAf0DUgGlAxQBGxwAA0kBhgMhAfsDLgH5A1MBpwMVARwcAAMGAQgDEgEXAyMB
MwM/AW4DWwHNAzoB9gNYAeoDVgG2Ay0BRCwAAz8BbAMuAfkDUwGnAxUBHAQAAw8BFANXAbkDAAH/A1gB
7QM/AW0DPwFtA1gB7QMAAf8DVwG5Aw8BFAQAAxUBHANTAacDLgH5Az8BbCAAAxQBGwNSAaUDHQH9A1UB
tAMmATgDBwEJOAADFgEeA1YBswMeAf0DHQH9A1IBpQMUARsQAAMQARUDRgF/A1wB2QNYAeoDXgHmA2EB
4QNgAeADXgHiA1wB5wNhAeEDUAGdAyEBMCQAAwIBAwMPARMDUQGeAx0B/QNSAaUDFAEbHAADSQGGAyEB
+wMuAfkDUwGnAxUBHBgAAwsBDgMtAUQDRgGBA1MBqQNdAd8DXQHoA18B2gNOAZYDKAE8AwkBDCwAAz8B
bAMuAfkDUwGnAxUBHAQAAw8BFANXAbkDAAH/A1gB7QM/AW0DPwFtA1gB7QMAAf8DVwG5Aw8BFAQAAxUB
HANTAacDLgH5Az8BbCAAAxQBGwNSAaUDHQH9A1UBtAMmATgDBwEJOAADFgEeA1YBswMeAf0DHQH9A1IB
pQMUARsQAAMTARoDTgGYA0IB9QMAAf8DYAHgA1YBtgNZAb4DXgHXAz0B9wMgAfwDWgHHAysBQiQAAw8B
EwNAAW8DXQHUA1MB7wNNAZIDEgEYHAADSQGGAyEB+wMuAfkDUwGnAxUBHBAABAIDDQERAzYBVwNYAbcD
WAHqA1wB7ANfAdUDSwGPAzoBYAMeASsDBgEHMAADPwFsAy4B+QNTAacDFQEcBAADDwEUA1cBuQMAAf8D
WAHtAz8BbQM/AW0DWAHtAwAB/wNXAbkDDwEUBAADFQEcA1MBpwMuAfkDPwFsIAADFAEbA1IBpQMdAf0D
VQG0AyYBOAMHAQk4AAMWAR4DVgGzAx4B/QMdAf0DUgGlAxQBGxAAAxQBGwNQAZoDOQH2AwAB/wNRAaQD
JAE0A0QBeANeAd0DPQH3A1sB3gM7AWMDDgESIAADAgEDAx4BKgNVAbQDPQH3A1EBoQMbASYDBQEGHAAD
SQGGAyEB+wMuAfkDUwGnAxUBHAwABAEDEwEZA0QBegNgAdsDOwH3Az0B9wNZAbsDKwFCAxMBGQMIAQoD
AgEDNAADPwFsAy4B+QNTAacDFQEcBAADDwEUA1cBuQMAAf8DWAHtAz8BbQM/AW0DWAHtAwAB/wNXAbkD
DwEUBAADFQEcA1MBpwMuAfkDPwFsIAADFAEbA1IBpQMdAf0DVQG0AyYBOAMHAQk4AAMWAR4DVgGzAx4B
/QMdAf0DUgGlAxQBGxAAAxQBGwNQAZoDOQH2AwAB/wNOAZUDMQFMA2EB4QMAAf8DWwHNAxoBJCgAAxUB
HANTAacDLgH5AyEB+wNJAYYkAANJAYYDIQH7Ay4B+QNTAacDFQEcDAADCwEOA00BkgMrAfkDAAH/AwAB
/wNVAa8DFgEdRAADPwFsAy4B+QNTAacDFQEcBAADDwEUA1cBuQMAAf8DWAHtAz8BbQM/AW0DWAHtAwAB
/wNXAbkDDwEUBAADFQEcA1MBpwMuAfkDPwFsIAADFAEbA1IBpQMdAf0DVgG2AygBPAMIAQo4AAMWAR4D
VgGzAx4B/QMdAf0DUgGlAxQBGxAAAxQBGwNQAZoDOQH2AwAB/wNDAfUDVAHvAyEB/AMRAf4DXQHMAx0B
KQQCGAAEAgMGAQcDDwETAzIBTwNZAcADQgH1A10B0QM6AWAkAANJAYYDIQH7Ay4B+QNTAacDFgEeAwwB
EAMqAUADVwG5A1oB6QNTAe8DWwHoA10BzwNGAX0DEwEaAwIBA0QAAz8BbAMuAfkDUwGnAxUBHAQAAw8B
FANXAbkDAAH/A1gB7QM/AW0DPwFtA1gB7QMAAf8DVwG5Aw8BFAQAAxUBHANTAacDLgH5Az8BbCAAAxQB
GwNSAaUDHQH9A1sB0AM/AWwDGAEhAw4BEgMOARIDDgESAw4BEgMOARIDDgESAw4BEgMOARIDDgESAw4B
EgMOARIDDgESAw4BEgMOARIDIAEuA1cBuQMeAf0DHQH9A1IBpQMUARsQAAMUARsDUAGaAzkB9gMAAf8D
AAH/AyMB+gNCAfUDHgH9A2AB4ANAAXEDHQEoAw4BEgMNAREDCQEMAwgBCgMLBA4BEgMcAScDOAFbA0QB
eQNaAccDYQHhA1YBtgM0AVQDDAEPJAADSQGGAyEB+wMuAfkDVQGuAyoBQAM/AW0DXQHRA0MB9QNWAe4D
WQG7A0QBeQMqAUADEQEWBAJIAAM/AWwDLgH5A1UBrgMgAS0DDgESAxsBJQNZAb4DAAH/A1gB7QM/AW0D
PwFtA1gB7QMAAf8DWQG+AxsBJQMOARIDIAEtA1UBrgMuAfkDPwFsIAADEwEaA1EBpAMfAfwDOQH2A10B
zANLAY0DRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YBgANGAYADRgGAA0YB
gANLAY8DXAHZAx4B/QNFAfQDTgGYAxMBGRAAAxIBGANLAYwDWAHtAwAB/wMgAf0DXAHZA1UBsQNdAd8D
QwH1A2AB4ANPAZsDRgGAA0QBegM5AV4DMwFQAz0BaANGAX4DUAGaA18B2gNbAeQDXwHaA08BmwMpAT4D
CgENKAADSQGGAyEB+wMgAfwDWwHTA1MBpgNcAdkDLgH5A2AB4ANQAZoDLQFFAxABFQMGAQcEAUwAAz8B
bAMgAfwDWwHTA0wBjgNGAYADSgGKA10B3AMeAf0DXQHfAzoBYgM6AWIDXQHfAx4B/QNdAdwDSgGKA0YB
gANMAY4DWwHTAyAB/AM/AWwgAAMSARcDSgGLA1oB6gMPAf4DJAH6A1IB7wNYAe0DWAHtA1gB7QNYAe0D
WAHtA1gB7QNYAe0DWAHtA1gB7QNYAe0DWAHtA1gB7QNYAe0DWAHtA1IB7wMkAfoDHgH9A1cBwgM0AVQD
CwEOEAADCAEKAy4BSANVAbEDXgHiA2AB2wNPAZsDLQFEA0MBdwNdAcwDYQHhA1gB6gNYAe0DWgHpA1sB
0wNcAcgDXwHaA1wB6wNOAfIDLgH5A14B0gNEAXgDIQEvAwcBCSwAA0IBdQNYAeoDAQH/Ay4B+QNQAfAD
XAHsA1wB2QNEAXsDHgEqAwYBCFgAAz8BbAMBAf8DLgH5A1IB7wNYAe0DVgHuAyQB+gM5AfYDUAGdAyAB
LQMgAS0DUAGdAzkB9gMkAfoDVgHuA1gB7QNSAe8DLgH5Aw8B/gM/AWwgAAMFAQYDGgEjA00BkwNgAeYD
WgHtAzwB9gM9AfcDPQH3Az0B9wM9AfcDPQH3Az0B9wM9AfcDPQH3Az0B9wM9AfcDPQH3Az0B9wM9AfcD
PQH3AzwB9gNaAe0DXwHlA0cBgwMKAQ0EAhAABAEDCAEKAx8BLAMuAUgDLQFEAxsBJQMHAQkDDwETAyMB
MgMuAUcDVwG5A10B6ANaAekDVwHuA1UB8QNcAewDWgHpA10B6ANbAdADNAFTAw8BEwMCAQMwAAMWAR4D
RwGDA1oB7QNVAfEDXwHVA0wBjgMrAUIDDwEUBAJcAAM6AWIDWgHpA1oB7QM8AfYDPQH3AzwB9gNcAewD
XQHcAzwBZgMGAQgDBgEIAzwBZgNdAdwDWgHtAzwB9gM9AfcDPAH2A1oB7QNgAeYDOgFiLAAEAQMjATMD
TgGXA1QBqwNUAasDVAGrA1QBqwNUAasDVAGrA1QBqwNUAasDVAGrA1QBqwNUAasDVAGrA1QBqwNUAasD
TgGXAyMBMwQBTAADCQELAzkBXQNHAYIDJwE6AwQBBUgABAIDIgExAzoBYQMPARRwAAMDAQQDKAE7A04B
mANUAasDUQGeAyEBLxQAAwMBBAMlATcDUAGfA1QBqwNOAZgDKAE7AwMBBBgAAUIBTQE+BwABPgMAASgD
AAF8AwABMAMAAQEBAAEBBgABAxYAA/8BAAH8AQMB8AE/AQMB8AEPAcAIAAH8AQEB8AE/AQMB8AEHAcAI
AAH8AQABMAE/AQAB8AEDAYAIAAH8AQABEAE/AQABcAEAAYAIAAH8AgABPwEAATABAAGACAAB/AIAAT8B
AAEwAQABgAgAAfwCAAE/DAAB/AEIAQABPwEICwAB/AEMAQABPwEMAQABIAkAAfwBDwEAAT8BDAEAATAJ
AAH8AQ8BgAE/AQ4BAAE4CQAB/AEPAfABPwEPAcABPwkAAfwBDwGAAT8BDgEAATgJAAH8AQ8BAAE/AQwB
AAEwCQAB/AEMAQABPwEMAQABIAkAAfwBCAEAAT8BCAsAAfwCAAE/DAAB/AIAAT8BAAEwCgAB/AIAAT8B
AAEwAQABgAgAAfwBAAEQAT8BAAFwAQABgAgAAfwBAAEwAT8BAAHwAQMBgAgAAfwBAAHwAT8BAQHwAQcB
wAgAAfwBAwHwAT8BAwHwAQ8BwAgAAf4BHwH4AX8BDwH4AX8BwAgAAeACAAEHAf4BAAEBAf8B4AEPAv8B
4AEAAQEB8AHgAgABBwH8AgAB/wHgAQcC/wHgAQABAQHwAeACAAEHAfwCAAF/AeABAwL/AeABAAEBAfAB
4AIAAQcB/AIAAT8B4AEAAX8B/wHgAQABAQHwAeABfwH+AQcB/AEHAcABPwHgAQABPwH/AeEBAAEhAfAB
4AF/Af4BBwL/AfgBPwHgAcABPwH/AeEBAAEhAfAB4AF/Af4BBwL/AfgBDwHgAcABAwH/AeEBAAEhAfAB
4AF/Af4BBwL/AfwBDwHgAfABAQH/AeEBAAEhAfAB4AF/Af4BBwL/AfwBDwHgAfwBAAH/AeEBAAEhAfAB
4AF/Af4BBwP/AQ8B4AH+AQAB/wHhAQABIQHwAeABfwH+AQcD/wEPAeAB/wEAAX8B4QEAASEB8AHgAX8B
/gEHA/8BDwHgAf8B8AF/AeEBAAEhAfAB4AF/Af4BBwGAAQcB/wEPAeAB/wEAAX8B4QEAASEB8AHgAX8B
/gEHAYABBwH/AQ8B4AH+AQAB/wHhAQABIQHwAeABfwH+AQcBgAEHAfwBDwHgAfwBAAH/AeEBAAEhAfAB
4AF/Af4BBwGAAQcB/AEPAeAB8AEBAf8B4QEAASEB8AHgAX8B/gEHAYABBwH4AQ8C4AEDAf8B4QEAASEB
8AHgAX8B/gEHAYABHwH4AT8C4AE/Af8B4QEAASEB8AHgAX8B/gEHAYABDwHAAT8B4AEAAT8B/wHhAQAB
IQHwAeACAAEHAYACAAE/AeABAAF/Af8B4AEAAQEB8AHgAgABBwGAAgABfwHgAQAC/wHgAQABAQHwAeAC
AAEHAYACAAH/AeABBwL/AeABAAEBAfAB4AIAAQcBgAEAAQEB/wHgAQ8C/wHgAQABAQHwAfwCAAE/Af8B
+AE/Af8B8AP/AfABPgEDAfAL
</value>
</data>
<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>

View 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;
}
}

View 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();
}
}
}

View 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>

View 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="&gt;&gt;propertyGrid_Animation.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;contextMenuStrip_Skin.Name" xml:space="preserve">
<value>contextMenuStrip_Skin</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tabPage_Skin.Name" xml:space="preserve">
<value>tabPage_Skin</value>
</data>
<data name="&gt;&gt;tabPage_Debug.Name" xml:space="preserve">
<value>tabPage_Debug</value>
</data>
<data name="&gt;&gt;propertyGrid_BaseInfo.Type" xml:space="preserve">
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;contextMenuStrip_Animation.Name" xml:space="preserve">
<value>contextMenuStrip_Animation</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;propertyGrid_Debug.Name" xml:space="preserve">
<value>propertyGrid_Debug</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;propertyGrid_Transform.Name" xml:space="preserve">
<value>propertyGrid_Transform</value>
</data>
<data name="toolStripMenuItem_RemoveAnimation.Text" xml:space="preserve">
<value>移除</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;toolStripMenuItem_ReloadSkins.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;contextMenuStrip_Skin.Type" xml:space="preserve">
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;tabControl.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;propertyGrid_Skin.Type" xml:space="preserve">
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;propertyGrid_Debug.Type" xml:space="preserve">
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tabPage_Skin.Parent" xml:space="preserve">
<value>tabControl</value>
</data>
<data name="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;tabPage_Transform.Parent" xml:space="preserve">
<value>tabControl</value>
</data>
<data name="&gt;&gt;tabPage_Render.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tabPage_Slot.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tabPage_Animation.Name" xml:space="preserve">
<value>tabPage_Animation</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;tabPage_BaseInfo.Parent" xml:space="preserve">
<value>tabControl</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>SpineViewPropertyGrid</value>
</data>
<data name="&gt;&gt;tabControl.Type" xml:space="preserve">
<value>System.Windows.Forms.TabControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tabPage_Debug.Parent" xml:space="preserve">
<value>tabControl</value>
</data>
<data name="&gt;&gt;tabPage_Slot.Name" xml:space="preserve">
<value>tabPage_Slot</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tabPage_BaseInfo.Name" xml:space="preserve">
<value>tabPage_BaseInfo</value>
</data>
<data name="&gt;&gt;propertyGrid_BaseInfo.Parent" xml:space="preserve">
<value>tabPage_BaseInfo</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;propertyGrid_Debug.Parent" xml:space="preserve">
<value>tabPage_Debug</value>
</data>
<data name="&gt;&gt;tabPage_Transform.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tabPage_Debug.ZOrder" xml:space="preserve">
<value>6</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;toolStripMenuItem_AddAnimation.Name" xml:space="preserve">
<value>toolStripMenuItem_AddAnimation</value>
</data>
<data name="&gt;&gt;tabPage_Animation.ZOrder" xml:space="preserve">
<value>5</value>
</data>
<data name="&gt;&gt;propertyGrid_Render.Name" xml:space="preserve">
<value>propertyGrid_Render</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;tabPage_Render.Type" xml:space="preserve">
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_ReloadSkins.Name" xml:space="preserve">
<value>toolStripMenuItem_ReloadSkins</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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>

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -117,15 +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="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>
<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>
@@ -3273,4 +3270,7 @@
////////wAAAAAAAB///////
</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>About SpineViewer</value>
</data>
</root>

View File

@@ -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="&gt;&gt;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="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;label3.Parent" xml:space="preserve">
<value>tableLayoutPanel_About</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;$this.Name" xml:space="preserve">
<value>AboutDialog</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel1.Type" xml:space="preserve">
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;label3.Name" xml:space="preserve">
<value>label3</value>
</data>
<data name="&gt;&gt;label_Version.Parent" xml:space="preserve">
<value>tableLayoutPanel_About</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;panel1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="label3.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="label3" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="label1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="label_Version" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="linkLabel_RepoUrl" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,28.571428,Percent,71.42857" /&gt;&lt;Rows Styles="AutoSize,0,AutoSize,0,Percent,100" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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>

View File

@@ -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;

View File

@@ -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>
/// 路径列表

File diff suppressed because it is too large Load Diff

View File

@@ -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="&gt;&gt;panel.Name" xml:space="preserve">
<value>panel</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;$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="&gt;&gt;skelFileListBox.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="&gt;&gt;label4.Name" xml:space="preserve">
<value>label4</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tableLayoutPanel2.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;label3.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;label4.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tableLayoutPanel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;button_Ok.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;button_Ok.Parent" xml:space="preserve">
<value>tableLayoutPanel2</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;button_Ok.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tableLayoutPanel2.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;skelFileListBox.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;button_Cancel.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="label4" Row="0" RowSpan="1" Column="0" ColumnSpan="4" /&gt;&lt;Control Name="label3" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="comboBox_Version" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="tableLayoutPanel2" Row="3" RowSpan="1" Column="0" ColumnSpan="4" /&gt;&lt;Control Name="skelFileListBox" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,Percent,100,AutoSize,0,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="tableLayoutPanel2.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
<value>GrowAndShrink</value>
</data>
<data name="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,50,Percent,50" /&gt;&lt;Rows Styles="AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</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="&gt;&gt;panel.Type" xml:space="preserve">
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Parent" xml:space="preserve">
<value>panel</value>
</data>
<data name="&gt;&gt;skelFileListBox.Type" xml:space="preserve">
<value>SpineViewer.Controls.SkelFileListBox, SpineViewer, Culture=neutral, PublicKeyToken=null</value>
</data>
<data name="&gt;&gt;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>

View File

@@ -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;
}
}

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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="&gt;&gt;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="&gt;&gt;flowLayoutPanel_TargetFormat.ZOrder" xml:space="preserve">
<value>2</value>
</data>
<data name="button_Ok.Text" xml:space="preserve">
<value>确认</value>
</data>
<data name="&gt;&gt;label1.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;radioButton_JsonTarget.Type" xml:space="preserve">
<value>System.Windows.Forms.RadioButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="textBox_OutputDir.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;tableLayoutPanel1.Parent" xml:space="preserve">
<value>panel</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;button_Ok.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tableLayoutPanel2.ZOrder" xml:space="preserve">
<value>7</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;label2.Name" xml:space="preserve">
<value>label2</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;radioButton_JsonTarget.Name" xml:space="preserve">
<value>radioButton_JsonTarget</value>
</data>
<data name="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;flowLayoutPanel_TargetFormat.Type" xml:space="preserve">
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;button_Ok.Name" xml:space="preserve">
<value>button_Ok</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;flowLayoutPanel_TargetFormat.Name" xml:space="preserve">
<value>flowLayoutPanel_TargetFormat</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;$this.Name" xml:space="preserve">
<value>ConvertFileFormatDialog</value>
</data>
<data name="tableLayoutPanel2.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;label2.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;label3.Name" xml:space="preserve">
<value>label3</value>
</data>
<data name="label4.Text" xml:space="preserve">
<value>说明:输出文件夹留空则在每个文件同级目录下生成目标格式后缀的文件,视情况会覆盖已存在文件</value>
</data>
<data name="&gt;&gt;comboBox_SourceVersion.Name" xml:space="preserve">
<value>comboBox_SourceVersion</value>
</data>
<data name="&gt;&gt;radioButton_BinaryTarget.Type" xml:space="preserve">
<value>System.Windows.Forms.RadioButton, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="label5" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="comboBox_TargetVersion" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="flowLayoutPanel_TargetFormat" Row="5" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="label1" Row="4" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="label4" Row="0" RowSpan="1" Column="0" ColumnSpan="4" /&gt;&lt;Control Name="label3" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="comboBox_SourceVersion" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="tableLayoutPanel2" Row="6" RowSpan="1" Column="0" ColumnSpan="4" /&gt;&lt;Control Name="label2" Row="5" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="skelFileListBox" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /&gt;&lt;Control Name="tableLayoutPanel3" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,Percent,100" /&gt;&lt;Rows Styles="AutoSize,0,Percent,100,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,Absolute,24" /&gt;&lt;/TableLayoutSettings&gt;</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="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,50,Percent,50" /&gt;&lt;Rows Styles="AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;tableLayoutPanel1.Name" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;tableLayoutPanel3.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;label2.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;label5.Name" xml:space="preserve">
<value>label5</value>
</data>
<data name="tableLayoutPanel3.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="textBox_OutputDir" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="button_SelectOutputDir" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,Percent,100,AutoSize,0" /&gt;&lt;Rows Styles="Percent,100" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;label4.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;label4.Name" xml:space="preserve">
<value>label4</value>
</data>
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;comboBox_TargetVersion.Name" xml:space="preserve">
<value>comboBox_TargetVersion</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel.Name" xml:space="preserve">
<value>panel</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;radioButton_BinaryTarget.Parent" xml:space="preserve">
<value>flowLayoutPanel_TargetFormat</value>
</data>
<data name="&gt;&gt;label2.ZOrder" xml:space="preserve">
<value>8</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;panel.Type" xml:space="preserve">
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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>

View File

@@ -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;

View File

@@ -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);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -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="&gt;&gt;button_Copy.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tableLayoutPanel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="button_Copy" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="propertyGrid" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="Percent,100,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;tableLayoutPanel1.Name" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;propertyGrid.Name" xml:space="preserve">
<value>propertyGrid</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;propertyGrid.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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>

View File

@@ -20,133 +20,89 @@
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(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
//
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(710, 698);
panel1.TabIndex = 2;
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(propertyGrid_ExportArgs, 0, 0);
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 1);
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.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel1.Size = new Size(610, 673);
tableLayoutPanel1.TabIndex = 0;
//
// propertyGrid_ExportArgs
//
propertyGrid_ExportArgs.Dock = DockStyle.Fill;
propertyGrid_ExportArgs.Location = new Point(3, 3);
propertyGrid_ExportArgs.Name = "propertyGrid_ExportArgs";
propertyGrid_ExportArgs.PropertySort = PropertySort.Categorized;
propertyGrid_ExportArgs.Size = new Size(604, 594);
propertyGrid_ExportArgs.TabIndex = 1;
propertyGrid_ExportArgs.ToolbarVisible = false;
//
// tableLayoutPanel2
//
tableLayoutPanel2.AutoSize = true;
tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel2.ColumnCount = 2;
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, 630);
tableLayoutPanel2.Margin = new Padding(3, 30, 3, 3);
tableLayoutPanel2.Name = "tableLayoutPanel2";
tableLayoutPanel2.RowCount = 1;
tableLayoutPanel2.RowStyles.Add(new RowStyle());
tableLayoutPanel2.Size = new Size(604, 40);
tableLayoutPanel2.TabIndex = 10;
//
// button_Ok
//
button_Ok.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
button_Ok.Location = new Point(160, 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(332, 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;
//
// ExportDialog
//
AcceptButton = button_Ok;
AutoScaleDimensions = new SizeF(11F, 24F);
AutoScaleMode = AutoScaleMode.Font;
CancelButton = button_Cancel;
ClientSize = new Size(710, 698);
Controls.Add(panel1);
FormBorderStyle = FormBorderStyle.FixedDialog;
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
MinimizeBox = false;
Name = "ExportDialog";
ShowInTaskbar = false;
StartPosition = FormStartPosition.CenterScreen;
Text = "导出参数";
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(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
#endregion
private Panel panel1;
private Panel panel1;
private TableLayoutPanel tableLayoutPanel1;
private TableLayoutPanel tableLayoutPanel2;
private Button button_Ok;

View File

@@ -1,84 +1,71 @@
using SpineViewer.Exporter;
using SpineViewer.Utils;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Imaging;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SpineViewer.Spine.SpineExporter;
namespace SpineViewer.Dialogs
{
public partial class ExportDialog: Form
public partial class ExportDialog : Form
{
/// <summary>
/// 要绑定的导出参数
/// </summary>
public required ExportArgs ExportArgs
{
get => propertyGrid_ExportArgs.SelectedObject as ExportArgs;
init
{
propertyGrid_ExportArgs.SelectedObject = value;
private readonly ExporterProperty 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 != "导出") 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
}
}
public ExportDialog()
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 (ExportArgs.Validate() is string error)
{
MessageBox.Info(error, "参数错误");
if (wrapper.Exporter.Validate() is string error)
{
MessagePopup.Info(error, Properties.Resources.parameterError);
return;
}
DialogResult = DialogResult.OK;

File diff suppressed because it is too large Load Diff

View File

@@ -117,7 +117,100 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="button_Ok.Text" xml:space="preserve">
<value>确认</value>
</data>
<data name="&gt;&gt;panel1.Name" xml:space="preserve">
<value>panel1</value>
</data>
<data name="button_Cancel.Text" xml:space="preserve">
<value>取消</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="button_Ok.TabIndex" type="System.Int32, mscorlib">
<value>7</value>
</data>
<data name="&gt;&gt;propertyGrid_ExportArgs.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="$this.Text" xml:space="preserve">
<value>导出参数</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="propertyGrid_ExportArgs.Location" type="System.Drawing.Point, System.Drawing">
<value>2, 2</value>
</data>
<data name="button_Ok.Size" type="System.Drawing.Size, System.Drawing">
<value>81, 28</value>
</data>
<data name="&gt;&gt;propertyGrid_ExportArgs.Type" xml:space="preserve">
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>8, 20</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<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>577, 701</value>
</data>
<data name="&gt;&gt;propertyGrid_ExportArgs.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tableLayoutPanel2.ColumnCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>ExportDialog</value>
</data>
<data name="propertyGrid_ExportArgs.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="tableLayoutPanel2.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>2, 25, 2, 2</value>
</data>
<data name="tableLayoutPanel2.TabIndex" type="System.Int32, mscorlib">
<value>10</value>
</data>
<data name="&gt;&gt;panel1.Type" xml:space="preserve">
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="propertyGrid_ExportArgs.Size" type="System.Drawing.Size, System.Drawing">
<value>501, 618</value>
</data>
<data name="&gt;&gt;button_Ok.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;tableLayoutPanel2.Type" xml:space="preserve">
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>2, 2, 2, 2</value>
</data>
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
<value>505, 681</value>
</data>
<data name="&gt;&gt;tableLayoutPanel2.Name" xml:space="preserve">
<value>tableLayoutPanel2</value>
</data>
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
<value>0, 0</value>
</data>
<data name="tableLayoutPanel2.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="&gt;&gt;button_Cancel.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableLayoutPanel2.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
@@ -3264,4 +3357,139 @@
////////wAAAAAAAB///////
</value>
</data>
<data name="&gt;&gt;panel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="tableLayoutPanel2.Size" type="System.Drawing.Size, System.Drawing">
<value>501, 32</value>
</data>
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
<value>0</value>
</data>
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
<value>577, 701</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.Location" type="System.Drawing.Point, System.Drawing">
<value>147, 2</value>
</data>
<data name="tableLayoutPanel2.Location" type="System.Drawing.Point, System.Drawing">
<value>2, 647</value>
</data>
<data name="button_Cancel.Size" type="System.Drawing.Size, System.Drawing">
<value>81, 28</value>
</data>
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>36, 12, 36, 8</value>
</data>
<data name="&gt;&gt;button_Cancel.Name" xml:space="preserve">
<value>button_Cancel</value>
</data>
<data name="&gt;&gt;propertyGrid_ExportArgs.Name" xml:space="preserve">
<value>propertyGrid_ExportArgs</value>
</data>
<data name="button_Cancel.TabIndex" type="System.Int32, mscorlib">
<value>8</value>
</data>
<data name="button_Cancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Name" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="tableLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="&gt;&gt;button_Ok.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Parent" xml:space="preserve">
<value>panel1</value>
</data>
<data name="tableLayoutPanel2.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Bottom</value>
</data>
<data name="button_Cancel.Location" type="System.Drawing.Point, System.Drawing">
<value>272, 2</value>
</data>
<data name="&gt;&gt;button_Cancel.Parent" xml:space="preserve">
<value>tableLayoutPanel2</value>
</data>
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
<value>CenterScreen</value>
</data>
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="propertyGrid_ExportArgs" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="tableLayoutPanel2" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="Percent,100,AutoSize,0,Absolute,17,Absolute,17" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;tableLayoutPanel2.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
<value>36, 12</value>
</data>
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
<data name="button_Ok.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>2, 2, 22, 2</value>
</data>
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
</data>
<data name="propertyGrid_ExportArgs.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>2, 2, 2, 2</value>
</data>
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="button_Ok.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Right</value>
</data>
<data name="tableLayoutPanel2.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
<value>GrowAndShrink</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;button_Ok.Parent" xml:space="preserve">
<value>tableLayoutPanel2</value>
</data>
<data name="tableLayoutPanel2.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,50,Percent,50" /&gt;&lt;Rows Styles="AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;button_Cancel.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>2, 2, 2, 2</value>
</data>
<data name="&gt;&gt;panel1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="tableLayoutPanel2.RowCount" type="System.Int32, mscorlib">
<value>1</value>
</data>
<data name="&gt;&gt;button_Ok.Name" xml:space="preserve">
<value>button_Ok</value>
</data>
<data name="propertyGrid_ExportArgs.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
<value>2, 2, 2, 2</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>

View File

@@ -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;

View File

@@ -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 文件路径

File diff suppressed because it is too large Load Diff

View File

@@ -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="&gt;&gt;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="&gt;&gt;button_SelectAtlas.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;textBox_AtlasPath.ZOrder" xml:space="preserve">
<value>8</value>
</data>
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="label4" Row="0" RowSpan="1" Column="0" ColumnSpan="4" /&gt;&lt;Control Name="label1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="label2" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="label3" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="textBox_SkelPath" Row="1" RowSpan="1" Column="1" ColumnSpan="2" /&gt;&lt;Control Name="button_SelectSkel" Row="1" RowSpan="1" Column="3" ColumnSpan="1" /&gt;&lt;Control Name="button_SelectAtlas" Row="2" RowSpan="1" Column="3" ColumnSpan="1" /&gt;&lt;Control Name="comboBox_Version" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;Control Name="textBox_AtlasPath" Row="2" RowSpan="1" Column="1" ColumnSpan="2" /&gt;&lt;Control Name="tableLayoutPanel2" Row="4" RowSpan="1" Column="0" ColumnSpan="4" /&gt;&lt;/Controls&gt;&lt;Columns Styles="AutoSize,0,Percent,50,Percent,50,AutoSize,0" /&gt;&lt;Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</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="&gt;&gt;label3.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>skel文件路径:</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;label1.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;button_SelectAtlas.ZOrder" xml:space="preserve">
<value>6</value>
</data>
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
<value>5</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;button_SelectSkel.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;button_Cancel.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="button_SelectAtlas.Text" xml:space="preserve">
<value>...</value>
</data>
<data name="&gt;&gt;panel1.Type" xml:space="preserve">
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;panel1.Name" xml:space="preserve">
<value>panel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;textBox_SkelPath.Name" xml:space="preserve">
<value>textBox_SkelPath</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel1.Parent" xml:space="preserve">
<value>$this</value>
</data>
<data name="&gt;&gt;button_Cancel.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label3.ZOrder" xml:space="preserve">
<value>3</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;button_SelectSkel.Name" xml:space="preserve">
<value>button_SelectSkel</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;textBox_SkelPath.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="&gt;&gt;button_Ok.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;label4.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;textBox_AtlasPath.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;label4.Name" xml:space="preserve">
<value>label4</value>
</data>
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
<value>True</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>OpenSpineDialog</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;button_SelectSkel.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;openFileDialog_Atlas.Type" xml:space="preserve">
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;label2.Type" xml:space="preserve">
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tableLayoutPanel2.ZOrder" xml:space="preserve">
<value>9</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;tableLayoutPanel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;tableLayoutPanel2.Name" xml:space="preserve">
<value>tableLayoutPanel2</value>
</data>
<data name="tableLayoutPanel2.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
<value>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,50,Percent,50" /&gt;&lt;Rows Styles="AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;button_Ok.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;panel1.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="&gt;&gt;button_Ok.Parent" xml:space="preserve">
<value>tableLayoutPanel2</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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>

View File

@@ -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;

View File

@@ -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)

View 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>

View File

@@ -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="&gt;&gt;button_Cancel.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;label_Tip.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="button_Cancel.Text" xml:space="preserve">
<value>取消</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;progressBar.Parent" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Parent" xml:space="preserve">
<value>panel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;label_Tip.Name" xml:space="preserve">
<value>label_Tip</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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>&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;TableLayoutSettings&gt;&lt;Controls&gt;&lt;Control Name="progressBar" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="button_Cancel" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;Control Name="label_Tip" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /&gt;&lt;/Controls&gt;&lt;Columns Styles="Percent,100" /&gt;&lt;Rows Styles="Percent,100,AutoSize,0,AutoSize,0" /&gt;&lt;/TableLayoutSettings&gt;</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;button_Cancel.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="&gt;&gt;tableLayoutPanel1.Name" xml:space="preserve">
<value>tableLayoutPanel1</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;progressBar.Name" xml:space="preserve">
<value>progressBar</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;$this.Name" xml:space="preserve">
<value>ProgressDialog</value>
</data>
<data name="&gt;&gt;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="&gt;&gt;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="&gt;&gt;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="&gt;&gt;$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="&gt;&gt;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="&gt;&gt;panel1.Type" xml:space="preserve">
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;button_Cancel.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;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>

View File

@@ -1,107 +0,0 @@
using SpineViewer.Spine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Design;
using System.Drawing.Imaging;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter
{
/// <summary>
/// 导出参数基类
/// </summary>
public abstract class ExportArgs
{
/// <summary>
/// 实现类缓存
/// </summary>
private static readonly Dictionary<ExportType, Type> ImplementationTypes = [];
static ExportArgs()
{
var impTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(ExportArgs).IsAssignableFrom(t) && !t.IsAbstract);
foreach (var type in impTypes)
{
var attr = type.GetCustomAttribute<ExportImplementationAttribute>();
if (attr is not null)
{
if (ImplementationTypes.ContainsKey(attr.ExportType))
throw new InvalidOperationException($"Multiple implementations found: {attr.ExportType}");
ImplementationTypes[attr.ExportType] = type;
}
}
Program.Logger.Debug("Find export args implementations: [{}]", string.Join(", ", ImplementationTypes.Keys));
}
/// <summary>
/// 创建指定类型导出参数
/// </summary>
public static ExportArgs New(ExportType exportType, Size resolution, SFML.Graphics.View view, bool renderSelectedOnly)
{
if (!ImplementationTypes.TryGetValue(exportType, out var type))
{
throw new NotImplementedException($"Not implemented type: {exportType}");
}
return (ExportArgs)Activator.CreateInstance(type, resolution, view, renderSelectedOnly);
}
public ExportArgs(Size resolution, SFML.Graphics.View view, bool renderSelectedOnly)
{
Resolution = resolution;
View = view;
RenderSelectedOnly = renderSelectedOnly;
}
/// <summary>
/// 输出文件夹
/// </summary>
[Editor(typeof(FolderNameEditor), typeof(UITypeEditor))]
[Category("导出"), DisplayName("输出文件夹"), Description("逐个导出时可以留空,将逐个导出到模型自身所在目录")]
public string? OutputDir { get; set; } = null;
/// <summary>
/// 导出单个
/// </summary>
[Category("导出"), DisplayName("导出单个"), Description("是否将模型在同一个画面上导出单个文件,否则逐个导出模型")]
public bool ExportSingle { get; set; } = false;
/// <summary>
/// 画面分辨率
/// </summary>
[TypeConverter(typeof(SizeConverter))]
[Category("导出"), DisplayName("分辨率"), Description("画面的宽高像素大小,请在预览画面参数面板进行调整")]
public Size Resolution { get; }
/// <summary>
/// 渲染视窗
/// </summary>
[Category("导出"), DisplayName("视图"), Description("画面的视图参数,请在预览画面参数面板进行调整")]
public SFML.Graphics.View View { get; }
/// <summary>
/// 是否仅渲染选中
/// </summary>
[Category("导出"), DisplayName("仅渲染选中"), Description("是否仅导出选中的模型,请在预览画面参数面板进行调整")]
public bool RenderSelectedOnly { get; }
/// <summary>
/// 检查参数是否合法并规范化参数值, 否则返回用户错误原因
/// </summary>
public virtual string? Validate()
{
if (!string.IsNullOrEmpty(OutputDir) && File.Exists(OutputDir))
return "输出文件夹无效";
if (!string.IsNullOrEmpty(OutputDir) && !Directory.Exists(OutputDir))
return $"文件夹 {OutputDir} 不存在";
if (ExportSingle && string.IsNullOrEmpty(OutputDir))
return "导出单个时必须提供输出文件夹";
OutputDir = string.IsNullOrEmpty(OutputDir) ? null : Path.GetFullPath(OutputDir);
return null;
}
}
}

View File

@@ -1,140 +0,0 @@
using FFMpegCore.Pipes;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter
{
/// <summary>
/// 导出类型
/// </summary>
public enum ExportType
{
Frame,
FrameSequence,
GIF,
MKV,
MP4,
MOV,
WebM
}
/// <summary>
/// 导出实现类标记
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class ExportImplementationAttribute : Attribute
{
public ExportType ExportType { get; }
public ExportImplementationAttribute(ExportType exportType)
{
ExportType = exportType;
}
}
/// <summary>
/// SFML.Graphics.Image 帧对象包装类
/// </summary>
public class SFMLImageVideoFrame(SFML.Graphics.Image image) : IVideoFrame, IDisposable
{
public int Width => (int)image.Size.X;
public int Height => (int)image.Size.Y;
public string Format => "rgba";
public void Serialize(Stream pipe) => pipe.Write(image.Pixels);
public async Task SerializeAsync(Stream pipe, CancellationToken token) => await pipe.WriteAsync(image.Pixels, token);
public void Dispose() => image.Dispose();
/// <summary>
/// Save the contents of the image to a file
/// </summary>
/// <param name="filename">Path of the file to save (overwritten if already exist)</param>
/// <returns>True if saving was successful</returns>
public bool SaveToFile(string filename) => image.SaveToFile(filename);
/// <summary>
/// Save the image to a buffer in memory The format of the image must be specified.
/// The supported image formats are bmp, png, tga and jpg. This function fails if
/// the image is empty, or if the format was invalid.
/// </summary>
/// <param name="output">Byte array filled with encoded data</param>
/// <param name="format">Encoding format to use</param>
/// <returns>True if saving was successful</returns>
public bool SaveToMemory(out byte[] output, string format) => image.SaveToMemory(out output, format);
/// <summary>
/// 获取 Winforms Bitmap 对象
/// </summary>
public Bitmap CopyToBitmap()
{
image.SaveToMemory(out var imgBuffer, "bmp");
using var stream = new MemoryStream(imgBuffer);
return new(new Bitmap(stream)); // 必须重复构造一个副本才能摆脱对流的依赖, 否则之后使用会报错
}
}
/// <summary>
/// 为帧导出创建的辅助类
/// </summary>
public static class ExportHelper
{
/// <summary>
/// 根据 Bitmap 文件格式获取合适的文件后缀
/// </summary>
public static string GetSuffix(this ImageFormat imageFormat)
{
if (imageFormat == ImageFormat.Icon) return ".ico";
else if (imageFormat == ImageFormat.Exif) return ".jpeg";
else return $".{imageFormat.ToString().ToLower()}";
}
#region
/// <summary>
/// 获取某个包围盒下合适的视图
/// </summary>
public static SFML.Graphics.View GetView(this RectangleF bounds, Size resolution, Padding padding)
=> bounds.GetView((uint)resolution.Width, (uint)resolution.Height, (uint)padding.Left, (uint)padding.Right, (uint)padding.Top, (uint)padding.Bottom);
/// <summary>
/// 获取某个包围盒下合适的视图
/// </summary>
public static SFML.Graphics.View GetView(this RectangleF bounds, uint width, uint height, Padding padding)
=> bounds.GetView(width, height, (uint)padding.Left, (uint)padding.Right, (uint)padding.Top, (uint)padding.Bottom);
/// <summary>
/// 获取某个包围盒下合适的视图
/// </summary>
public static SFML.Graphics.View GetView(this RectangleF bounds, Size resolution, uint paddingL = 1, uint paddingR = 1, uint paddingT = 1, uint paddingB = 1)
=> bounds.GetView((uint)resolution.Width, (uint)resolution.Height, paddingL, paddingR, paddingT, paddingB);
/// <summary>
/// 获取某个包围盒下合适的视图
/// </summary>
public static SFML.Graphics.View GetView(this RectangleF bounds, uint width, uint height, uint paddingL = 1, uint paddingR = 1, uint paddingT = 1, uint paddingB = 1)
{
float sizeX = bounds.Width;
float sizeY = bounds.Height;
float innerW = width - paddingL - paddingR;
float innerH = height - paddingT - paddingB;
float scale = 1;
if (sizeY / sizeX < innerH / innerW)
scale = sizeX / innerW; // 相同的 X, 视窗 Y 更大
else
scale = sizeY / innerH; // 相同的 Y, 视窗 X 更大
var x = bounds.X + bounds.Width / 2 + (paddingL - (float)paddingR) * scale;
var y = bounds.Y + bounds.Height / 2 + (paddingT - (float)paddingB) * scale;
var viewX = width * scale;
var viewY = height * scale;
return new(new(x, y), new(viewX, -viewY));
}
#endregion
}
}

View File

@@ -1,129 +0,0 @@
using SpineViewer.Spine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
namespace SpineViewer.Exporter
{
/// <summary>
/// 导出器基类
/// </summary>
public abstract class Exporter
{
/// <summary>
/// 实现类缓存
/// </summary>
private static readonly Dictionary<ExportType, Type> ImplementationTypes = [];
static Exporter()
{
var impTypes = Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(Exporter).IsAssignableFrom(t) && !t.IsAbstract);
foreach (var type in impTypes)
{
var attr = type.GetCustomAttribute<ExportImplementationAttribute>();
if (attr is not null)
{
if (ImplementationTypes.ContainsKey(attr.ExportType))
throw new InvalidOperationException($"Multiple implementations found: {attr.ExportType}");
ImplementationTypes[attr.ExportType] = type;
}
}
Program.Logger.Debug("Find exporter implementations: [{}]", string.Join(", ", ImplementationTypes.Keys));
}
/// <summary>
/// 创建指定类型导出参数
/// </summary>
public static Exporter New(ExportType exportType, ExportArgs exportArgs)
{
if (!ImplementationTypes.TryGetValue(exportType, out var type))
{
throw new NotImplementedException($"Not implemented type: {exportType}");
}
return (Exporter)Activator.CreateInstance(type, exportArgs);
}
/// <summary>
/// 导出参数
/// </summary>
public ExportArgs ExportArgs { get; }
/// <summary>
/// 可用于文件名的时间戳字符串
/// </summary>
protected readonly string timestamp;
public Exporter(ExportArgs exportArgs)
{
ExportArgs = exportArgs;
timestamp = DateTime.Now.ToString("yyMMddHHmmss");
}
/// <summary>
/// 获取供渲染的 SFML.Graphics.RenderTexture
/// </summary>
private SFML.Graphics.RenderTexture GetRenderTexture()
{
var tex = new SFML.Graphics.RenderTexture((uint)ExportArgs.Resolution.Width, (uint)ExportArgs.Resolution.Height);
tex.Clear(SFML.Graphics.Color.Transparent);
tex.SetView(ExportArgs.View);
return tex;
}
/// <summary>
/// 获取单个模型的单帧画面
/// </summary>
protected SFMLImageVideoFrame GetFrame(Spine.Spine spine)
{
// tex 必须临时创建, 随用随取, 防止出现跨线程的情况
using var tex = GetRenderTexture();
tex.Clear(SFML.Graphics.Color.Transparent);
tex.Draw(spine);
tex.Display();
return new(tex.Texture.CopyToImage());
}
/// <summary>
/// 获取模型列表的单帧画面
/// </summary>
protected SFMLImageVideoFrame GetFrame(Spine.Spine[] spinesToRender)
{
// tex 必须临时创建, 随用随取, 防止出现跨线程的情况
using var tex = GetRenderTexture();
tex.Clear(SFML.Graphics.Color.Transparent);
foreach (var spine in spinesToRender) tex.Draw(spine);
tex.Display();
return new(tex.Texture.CopyToImage());
}
/// <summary>
/// 每个模型在同一个画面进行导出
/// </summary>
protected abstract void ExportSingle(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null);
/// <summary>
/// 每个模型独立导出
/// </summary>
protected abstract void ExportIndividual(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null);
/// <summary>
/// 执行导出
/// </summary>
/// <param name="spines">要进行导出的 Spine 列表</param>
/// <param name="worker">用来执行该函数的 worker</param>
public virtual void Export(Spine.Spine[] spines, BackgroundWorker? worker = null)
{
var spinesToRender = spines.Where(sp => !ExportArgs.RenderSelectedOnly || sp.IsSelected).Reverse().ToArray();
if (ExportArgs.ExportSingle) ExportSingle(spinesToRender, worker);
else ExportIndividual(spinesToRender, worker);
Program.LogCurrentMemoryUsage();
}
}
}

View File

@@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter.Implementations.ExportArgs
{
/// <summary>
/// 单帧画面导出参数
/// </summary>
[ExportImplementation(ExportType.Frame)]
public class FrameExportArgs : SpineViewer.Exporter.ExportArgs
{
public FrameExportArgs(Size resolution, SFML.Graphics.View view, bool renderSelectedOnly) : base(resolution, view, renderSelectedOnly) { }
/// <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>
[Category("单帧画面"), DisplayName("文件名后缀"), Description("与图像格式匹配的文件名后缀")]
public string FileSuffix { get => imageFormat.GetSuffix(); }
/// <summary>
/// DPI
/// </summary>
[TypeConverter(typeof(SizeFConverter))]
[Category("单帧画面"), DisplayName("DPI"), Description("导出图像的每英寸像素数,用于调整图像的物理尺寸")]
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);
}
}

View File

@@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter.Implementations.ExportArgs
{
/// <summary>
/// 帧序列导出参数
/// </summary>
[ExportImplementation(ExportType.FrameSequence)]
public class FrameSequenceExportArgs : VideoExportArgs
{
public FrameSequenceExportArgs(Size resolution, SFML.Graphics.View view, bool renderSelectedOnly) : base(resolution, view, renderSelectedOnly) { }
/// <summary>
/// 文件名后缀
/// </summary>
[TypeConverter(typeof(SFMLImageFileSuffixConverter))]
[Category("帧序列参数"), DisplayName("文件名后缀"), Description("帧文件的后缀,同时决定帧图像格式")]
public string FileSuffix { get; set; } = ".png";
}
}

View File

@@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter.Implementations.ExportArgs
{
/// <summary>
/// GIF 导出参数
/// </summary>
[ExportImplementation(ExportType.GIF)]
public class GifExportArgs : VideoExportArgs
{
public GifExportArgs(Size resolution, SFML.Graphics.View view, bool renderSelectedOnly) : base(resolution, view, renderSelectedOnly)
{
// GIF 的帧率不能太高, 超过 50 帧反而会变慢
FPS = 25;
}
/// <summary>
/// 调色板最大颜色数量
/// </summary>
[Category("GIF 参数"), DisplayName("调色板最大颜色数量"), Description("设置调色板使用的最大颜色数量, 越多则色彩保留程度越高")]
public uint MaxColors { get => maxColors; set => maxColors = Math.Clamp(value, 2, 256); }
private uint maxColors = 256;
/// <summary>
/// 透明度阈值
/// </summary>
[Category("GIF 参数"), DisplayName("透明度阈值"), Description("小于该值的像素点会被认为是透明像素")]
public byte AlphaThreshold { get => alphaThreshold; set => alphaThreshold = value; }
private byte alphaThreshold = 128;
/// <summary>
/// 获取构造好的 FFMpegCore 自定义参数
/// </summary>
[Browsable(false)]
public string FFMpegCoreCustomArguments
{
get
{
var v = $"[0:v] split [s0][s1]";
var s0 = $"[s0] palettegen=reserve_transparent=1:max_colors={MaxColors} [p]";
var s1 = $"[s1][p] paletteuse=dither=bayer:alpha_threshold={AlphaThreshold}";
return $"-filter_complex \"{v};{s0};{s1}\"";
}
}
}
}

View File

@@ -1,43 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter.Implementations.ExportArgs
{
/// <summary>
/// 视频导出参数基类
/// </summary>
public abstract class VideoExportArgs : SpineViewer.Exporter.ExportArgs
{
public VideoExportArgs(Size resolution, SFML.Graphics.View view, bool renderSelectedOnly) : base(resolution, view, renderSelectedOnly) { }
/// <summary>
/// 导出时长
/// </summary>
[Category("视频参数"), DisplayName("时长"), Description("可以从模型列表查看动画时长, 如果小于 0, 则在逐个导出时每个模型使用各自的当前动画时长")]
public float Duration
{
get => duration;
set => duration = value < 0 ? -1 : value;
}
private float duration = -1;
/// <summary>
/// 帧率
/// </summary>
[Category("视频参数"), DisplayName("帧率"), Description("每秒画面数")]
public float FPS { get; set; } = 60;
public override string? Validate()
{
if (base.Validate() is string error)
return error;
if (ExportSingle && Duration < 0)
return "导出单个时导出时长不能为负数";
return null;
}
}
}

View File

@@ -1,86 +0,0 @@
using SpineViewer.Exporter.Implementations.ExportArgs;
using SpineViewer.Spine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter.Implementations.Exporter
{
/// <summary>
/// 单帧画面导出器
/// </summary>
[ExportImplementation(ExportType.Frame)]
public class FrameExporter : SpineViewer.Exporter.Exporter
{
public FrameExporter(FrameExportArgs exportArgs) : base(exportArgs) { }
protected override void ExportSingle(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null)
{
var args = (FrameExportArgs)ExportArgs;
// 导出单个时必定提供输出文件夹
var filename = $"frame_{timestamp}{args.FileSuffix}";
var savePath = Path.Combine(args.OutputDir, filename);
worker?.ReportProgress(0, $"已处理 0/1");
try
{
using var frame = GetFrame(spinesToRender);
using var img = frame.CopyToBitmap();
img.SetResolution(args.DPI.Width, args.DPI.Height);
img.Save(savePath, args.ImageFormat);
}
catch (Exception ex)
{
Program.Logger.Error(ex.ToString());
Program.Logger.Error("Failed to save single frame");
}
worker?.ReportProgress(100, $"已处理 1/1");
}
protected override void ExportIndividual(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null)
{
var args = (FrameExportArgs)ExportArgs;
int total = spinesToRender.Length;
int success = 0;
int error = 0;
worker?.ReportProgress(0, $"已处理 0/{total}");
for (int i = 0; i < total; i++)
{
var spine = spinesToRender[i];
// 逐个导出时如果提供了输出文件夹, 则全部导出到输出文件夹, 否则输出到各自的文件夹
var filename = $"{spine.Name}_{timestamp}{args.FileSuffix}";
var savePath = args.OutputDir is null ? Path.Combine(spine.AssetsDir, filename) : Path.Combine(args.OutputDir, filename);
try
{
using var frame = GetFrame(spine);
using var img = frame.CopyToBitmap();
img.SetResolution(args.DPI.Width, args.DPI.Height);
img.Save(savePath, args.ImageFormat);
success++;
}
catch (Exception ex)
{
Program.Logger.Error(ex.ToString());
Program.Logger.Error("Failed to save frame {} {}", savePath, spine.SkelPath);
error++;
}
worker?.ReportProgress((int)((i + 1) * 100.0) / total, $"已处理 {i + 1}/{total}");
}
if (error > 0)
Program.Logger.Warn("Frames save {} successfully, {} failed", success, error);
else
Program.Logger.Info("{} frames saved successfully", success);
}
}
}

View File

@@ -1,87 +0,0 @@
using SpineViewer.Exporter.Implementations.ExportArgs;
using SpineViewer.Spine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter.Implementations.Exporter
{
/// <summary>
/// 帧序列导出器
/// </summary>
[ExportImplementation(ExportType.FrameSequence)]
public class FrameSequenceExporter : VideoExporter
{
public FrameSequenceExporter(FrameSequenceExportArgs exportArgs) : base(exportArgs) { }
protected override void ExportSingle(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null)
{
var args = (FrameSequenceExportArgs)ExportArgs;
// 导出单个时必定提供输出文件夹,
var saveDir = Path.Combine(args.OutputDir, $"frames_{timestamp}_{args.FPS:f0}");
Directory.CreateDirectory(saveDir);
int frameIdx = 0;
foreach (var frame in GetFrames(spinesToRender, worker))
{
var filename = $"frames_{timestamp}_{args.FPS:f0}_{frameIdx:d6}{args.FileSuffix}";
var savePath = Path.Combine(saveDir, filename);
try
{
frame.SaveToFile(savePath);
}
catch (Exception ex)
{
Program.Logger.Error(ex.ToString());
Program.Logger.Error("Failed to save frame {}", savePath);
}
finally
{
frame.Dispose();
}
frameIdx++;
}
}
protected override void ExportIndividual(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null)
{
var args = (FrameSequenceExportArgs)ExportArgs;
foreach (var spine in spinesToRender)
{
if (worker?.CancellationPending == true) break; // 取消的日志在 GetFrames 里输出
// 如果提供了输出文件夹, 则全部导出到输出文件夹, 否则导出到各自的文件夹下
var subDir = $"{spine.Name}_{timestamp}_{args.FPS:f0}";
var saveDir = args.OutputDir is null ? Path.Combine(spine.AssetsDir, subDir) : Path.Combine(args.OutputDir, subDir);
Directory.CreateDirectory(saveDir);
int frameIdx = 0;
foreach (var frame in GetFrames(spine, worker))
{
var filename = $"{spine.Name}_{timestamp}_{args.FPS:f0}_{frameIdx:d6}{args.FileSuffix}";
var savePath = Path.Combine(saveDir, filename);
try
{
frame.SaveToFile(savePath);
}
catch (Exception ex)
{
Program.Logger.Error(ex.ToString());
Program.Logger.Error("Failed to save frame {} {}", savePath, spine.SkelPath);
}
finally
{
frame.Dispose();
}
frameIdx++;
}
}
}
}
}

View File

@@ -1,76 +0,0 @@
using FFMpegCore.Pipes;
using FFMpegCore;
using SpineViewer.Exporter.Implementations.ExportArgs;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFMpegCore.Arguments;
namespace SpineViewer.Exporter.Implementations.Exporter
{
/// <summary>
/// GIF 动图导出器
/// </summary>
[ExportImplementation(ExportType.GIF)]
public class GifExporter : VideoExporter
{
public GifExporter(GifExportArgs exportArgs) : base(exportArgs) { }
protected override void ExportSingle(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null)
{
var args = (GifExportArgs)ExportArgs;
// 导出单个时必定提供输出文件夹
var filename = $"{timestamp}_{args.FPS:f0}_{args.MaxColors}_{args.AlphaThreshold}.gif";
var savePath = Path.Combine(args.OutputDir, filename);
var videoFramesSource = new RawVideoPipeSource(GetFrames(spinesToRender, worker)) { FrameRate = args.FPS };
try
{
FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(savePath, true, options => options
.ForceFormat("gif")
.WithCustomArgument(args.FFMpegCoreCustomArguments))
.ProcessSynchronously();
}
catch (Exception ex)
{
Program.Logger.Error(ex.ToString());
Program.Logger.Error("Failed to export gif {}", savePath);
}
}
protected override void ExportIndividual(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null)
{
var args = (GifExportArgs)ExportArgs;
foreach (var spine in spinesToRender)
{
if (worker?.CancellationPending == true) break; // 取消的日志在 GetFrames 里输出
// 如果提供了输出文件夹, 则全部导出到输出文件夹, 否则导出到各自的文件夹下
var filename = $"{spine.Name}_{timestamp}_{args.FPS:f0}_{args.MaxColors}_{args.AlphaThreshold}.gif";
var savePath = Path.Combine(args.OutputDir ?? spine.AssetsDir, filename);
var videoFramesSource = new RawVideoPipeSource(GetFrames(spine, worker)) { FrameRate = args.FPS };
try
{
FFMpegArguments
.FromPipeInput(videoFramesSource)
.OutputToFile(savePath, true, options => options
.ForceFormat("gif")
.WithCustomArgument(args.FFMpegCoreCustomArguments))
.ProcessSynchronously();
}
catch (Exception ex)
{
Program.Logger.Error(ex.ToString());
Program.Logger.Error("Failed to export gif {} {}", savePath, spine.SkelPath);
}
}
}
}
}

View File

@@ -1,82 +0,0 @@
using SpineViewer.Exporter.Implementations.ExportArgs;
using SpineViewer.Spine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter.Implementations.Exporter
{
/// <summary>
/// 视频导出基类
/// </summary>
public abstract class VideoExporter : SpineViewer.Exporter.Exporter
{
public VideoExporter(VideoExportArgs exportArgs) : base(exportArgs) { }
/// <summary>
/// 生成单个模型的帧序列
/// </summary>
protected IEnumerable<SFMLImageVideoFrame> GetFrames(Spine.Spine spine, BackgroundWorker? worker = null)
{
var args = (VideoExportArgs)ExportArgs;
// 独立导出时如果 args.Duration 小于 0 则使用自己的动画时长
var duration = args.Duration;
if (duration < 0) duration = spine.CurrentAnimationDuration;
float delta = 1f / args.FPS;
int total = Math.Max(1, (int)(duration * args.FPS)); // 至少导出 1 帧
worker?.ReportProgress(0, $"{spine.Name} 已处理 0/{total} 帧");
for (int i = 0; i < total; i++)
{
if (worker?.CancellationPending == true)
{
Program.Logger.Info("Export cancelled");
break;
}
var frame = GetFrame(spine);
spine.Update(delta);
worker?.ReportProgress((int)((i + 1) * 100.0) / total, $"{spine.Name} 已处理 {i + 1}/{total} 帧");
yield return frame;
}
}
/// <summary>
/// 生成多个模型的帧序列
/// </summary>
protected IEnumerable<SFMLImageVideoFrame> GetFrames(Spine.Spine[] spinesToRender, BackgroundWorker? worker = null)
{
// 导出单个时必须根据 args.Duration 决定导出时长
var args = (VideoExportArgs)ExportArgs;
float delta = 1f / args.FPS;
int total = Math.Max(1, (int)(args.Duration * args.FPS)); // 至少导出 1 帧
worker?.ReportProgress(0, $"已处理 0/{total} 帧");
for (int i = 0; i < total; i++)
{
if (worker?.CancellationPending == true)
{
Program.Logger.Info("Export cancelled");
break;
}
var frame = GetFrame(spinesToRender);
foreach (var spine in spinesToRender) spine.Update(delta);
worker?.ReportProgress((int)((i + 1) * 100.0) / total, $"已处理 {i + 1}/{total} 帧");
yield return frame;
}
}
public override void Export(Spine.Spine[] spines, BackgroundWorker? worker = null)
{
// 导出视频格式需要把模型时间都重置到 0
foreach (var spine in spines) spine.CurrentAnimation = spine.CurrentAnimation;
base.Export(spines, worker);
}
}
}

View File

@@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SpineViewer.Exporter
{
public class SFMLImageFileSuffixConverter : StringConverter
{
private readonly string[] supportedFileSuffix = [".png", ".jpg", ".tga", ".bmp"];
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context)
{
// 支持标准值列表
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context)
{
// 排他模式,只有下拉列表中的值可选
return true;
}
public override StandardValuesCollection? GetStandardValues(ITypeDescriptorContext? context)
{
return new StandardValuesCollection(supportedFileSuffix);
}
}
}

View 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);
}
}
}

View 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);
}
}
}

View 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
}
}

View 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;
}
}
}
}

View 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>

View File

@@ -1,6 +1,6 @@
namespace SpineViewer
{
partial class MainForm
partial class SpineViewerForm
{
/// <summary>
/// Required designer variable.
@@ -29,7 +29,20 @@
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();
@@ -38,13 +51,23 @@
toolStripMenuItem_Export = new ToolStripMenuItem();
toolStripMenuItem_ExportFrame = new ToolStripMenuItem();
toolStripMenuItem_ExportFrameSequence = new ToolStripMenuItem();
toolStripSeparator4 = new ToolStripSeparator();
toolStripMenuItem_ExportGif = new ToolStripMenuItem();
toolStripMenuItem_ExportMkv = new ToolStripMenuItem();
toolStripMenuItem_ExportWebp = new ToolStripMenuItem();
toolStripMenuItem_ExportAvif = new ToolStripMenuItem();
toolStripSeparator5 = new ToolStripSeparator();
toolStripMenuItem_ExportMp4 = new ToolStripMenuItem();
toolStripMenuItem_ExportMov = 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_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();
@@ -53,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();
@@ -86,195 +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_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, 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(270, 34);
toolStripMenuItem_Open.Text = "打开(&O)...";
toolStripMenuItem_Open.Click += toolStripMenuItem_Open_Click;
//
// toolStripMenuItem_BatchOpen
//
toolStripMenuItem_BatchOpen.Name = "toolStripMenuItem_BatchOpen";
toolStripMenuItem_BatchOpen.Size = new Size(270, 34);
toolStripMenuItem_BatchOpen.Text = "批量打开(&B)...";
toolStripMenuItem_BatchOpen.Click += toolStripMenuItem_BatchOpen_Click;
//
// toolStripSeparator1
//
toolStripSeparator1.Name = "toolStripSeparator1";
toolStripSeparator1.Size = new Size(267, 6);
//
// toolStripMenuItem_Export
//
toolStripMenuItem_Export.DropDownItems.AddRange(new ToolStripItem[] { toolStripMenuItem_ExportFrame, toolStripMenuItem_ExportFrameSequence, toolStripMenuItem_ExportGif, toolStripMenuItem_ExportMkv, toolStripMenuItem_ExportMp4, toolStripMenuItem_ExportMov, toolStripMenuItem_ExportWebm });
toolStripMenuItem_Export.Name = "toolStripMenuItem_Export";
toolStripMenuItem_Export.Size = new Size(270, 34);
toolStripMenuItem_Export.Text = "导出(&E)";
//
// toolStripMenuItem_ExportFrame
//
toolStripMenuItem_ExportFrame.Name = "toolStripMenuItem_ExportFrame";
toolStripMenuItem_ExportFrame.Size = new Size(270, 34);
toolStripMenuItem_ExportFrame.Text = "单帧画面...";
toolStripMenuItem_ExportFrame.Click += toolStripMenuItem_Export_Click;
//
// toolStripMenuItem_ExportFrameSequence
//
toolStripMenuItem_ExportFrameSequence.Name = "toolStripMenuItem_ExportFrameSequence";
toolStripMenuItem_ExportFrameSequence.Size = new Size(270, 34);
toolStripMenuItem_ExportFrameSequence.Text = "帧序列...";
toolStripMenuItem_ExportFrameSequence.Click += toolStripMenuItem_Export_Click;
//
// toolStripMenuItem_ExportGif
//
toolStripMenuItem_ExportGif.Name = "toolStripMenuItem_ExportGif";
toolStripMenuItem_ExportGif.Size = new Size(270, 34);
toolStripMenuItem_ExportGif.Text = "GIF...";
toolStripMenuItem_ExportGif.Click += toolStripMenuItem_Export_Click;
//
// toolStripMenuItem_ExportMkv
//
toolStripMenuItem_ExportMkv.Name = "toolStripMenuItem_ExportMkv";
toolStripMenuItem_ExportMkv.Size = new Size(270, 34);
toolStripMenuItem_ExportMkv.Text = "MKV";
toolStripMenuItem_ExportMkv.Click += toolStripMenuItem_Export_Click;
//
// toolStripMenuItem_ExportMp4
//
toolStripMenuItem_ExportMp4.Name = "toolStripMenuItem_ExportMp4";
toolStripMenuItem_ExportMp4.Size = new Size(270, 34);
toolStripMenuItem_ExportMp4.Text = "MP4...";
toolStripMenuItem_ExportMp4.Click += toolStripMenuItem_Export_Click;
//
// toolStripMenuItem_ExportMov
//
toolStripMenuItem_ExportMov.Name = "toolStripMenuItem_ExportMov";
toolStripMenuItem_ExportMov.Size = new Size(270, 34);
toolStripMenuItem_ExportMov.Text = "MOV...";
toolStripMenuItem_ExportMov.Click += toolStripMenuItem_Export_Click;
//
// toolStripMenuItem_ExportWebm
//
toolStripMenuItem_ExportWebm.Name = "toolStripMenuItem_ExportWebm";
toolStripMenuItem_ExportWebm.Size = new Size(270, 34);
toolStripMenuItem_ExportWebm.Text = "WebM...";
toolStripMenuItem_ExportWebm.Click += toolStripMenuItem_Export_Click;
//
// toolStripSeparator2
//
toolStripSeparator2.Name = "toolStripSeparator2";
toolStripSeparator2.Size = new Size(267, 6);
//
// toolStripMenuItem_Exit
//
toolStripMenuItem_Exit.Name = "toolStripMenuItem_Exit";
toolStripMenuItem_Exit.ShortcutKeys = Keys.Alt | Keys.F4;
toolStripMenuItem_Exit.Size = new Size(270, 34);
toolStripMenuItem_Exit.Text = "退出(&X)";
toolStripMenuItem_Exit.Click += toolStripMenuItem_Exit_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
//
@@ -285,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;
@@ -295,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
@@ -308,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;
@@ -318,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
@@ -331,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;
@@ -341,143 +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.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;
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();
@@ -495,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();
@@ -517,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;
@@ -525,10 +538,9 @@
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 Controls.SpinePreviewPanel spinePreviewPanel;
private ToolStripMenuItem toolStripMenuItem_Diagnostics;
private ToolStripSeparator toolStripSeparator3;
private ToolStripMenuItem toolStripMenuItem_Download;
@@ -543,5 +555,23 @@
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;
}
}

View 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;
// }
//}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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
}
}

View 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);
}
}
}
}

View 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>

View File

@@ -1,250 +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;
using SpineViewer.Exporter;
namespace SpineViewer
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
InitializeLogConfiguration();
// 在此处将导出菜单需要的类绑定起来
toolStripMenuItem_ExportFrame.Tag = ExportType.Frame;
toolStripMenuItem_ExportFrameSequence.Tag = ExportType.FrameSequence;
toolStripMenuItem_ExportGif.Tag = ExportType.GIF;
toolStripMenuItem_ExportMkv.Tag = ExportType.MKV;
toolStripMenuItem_ExportMp4.Tag = ExportType.MP4;
toolStripMenuItem_ExportMov.Tag = ExportType.MOV;
toolStripMenuItem_ExportWebm.Tag = ExportType.WebM;
}
/// <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.StartRender();
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
spinePreviewer.StopRender();
}
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)
{
ExportType type = (ExportType)((ToolStripMenuItem)sender).Tag;
if (type == ExportType.Frame && spinePreviewer.IsUpdating)
{
if (MessageBox.Quest("画面仍在更新,建议手动暂停画面后导出固定的一帧,是否继续?") != DialogResult.OK)
return;
}
lock (spineListView.Spines)
{
if (spineListView.Spines.Count <= 0)
{
MessageBox.Info("请至少打开一个骨骼文件");
return;
}
}
var exportArgs = ExportArgs.New(type, spinePreviewer.Resolution, spinePreviewer.GetView(), spinePreviewer.RenderSelectedOnly);
var exportDialog = new Dialogs.ExportDialog() { ExportArgs = exportArgs };
if (exportDialog.ShowDialog() != DialogResult.OK)
return;
var exporter = Exporter.Exporter.New(type, exportArgs);
var progressDialog = new Dialogs.ProgressDialog();
progressDialog.DoWork += Export_Work;
progressDialog.RunWorkerAsync(exporter);
progressDialog.ShowDialog();
}
private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
{
Close();
}
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)
{
(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 Export_Work(object? sender, DoWorkEventArgs e)
{
var worker = (BackgroundWorker)sender;
var exporter = (Exporter.Exporter)e.Argument;
spinePreviewer.StopRender();
lock (spineListView.Spines) { exporter.Export(spineListView.Spines.ToArray(), (BackgroundWorker)sender); }
e.Cancel = worker.CancellationPending;
spinePreviewer.StartRender();
}
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);
}
}
//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;
// }
//}
}
}

View 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);
}
}
}

View 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;
}
}
}

View File

@@ -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);
}
}

File diff suppressed because it is too large Load Diff

View 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 1828 (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=&lt;encoder&gt;" to view supported encoder parameters.
Use "ffmpeg -h muxer=&lt;file format&gt;" 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. Its recommended to manually pause and export a fixed frame. Do you want to continue?</value>
</data>
</root>

View File

@@ -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=&lt;编码器&gt;\" 查看编码器支持的参数\n使用 \"ffmpeg -h muxer=&lt;文件格式&gt;\" 查看文件格式支持的参数</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>

View File

@@ -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

Some files were not shown because too many files have changed in this diff Show More