Compare commits
464 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2fecf4223a | ||
|
|
2953ec44fb | ||
|
|
77399b4524 | ||
|
|
c0e2bb81e5 | ||
|
|
55ebcc1857 | ||
|
|
292ede8461 | ||
|
|
63ed8d7ca4 | ||
|
|
ce7c6f3802 | ||
|
|
0b478cab18 | ||
|
|
b7f5f24e6f | ||
|
|
150331d2e4 | ||
|
|
4d1aec9ed8 | ||
|
|
0cb325820b | ||
|
|
2a862b28be | ||
|
|
c2935f49e9 | ||
|
|
22043f8f38 | ||
|
|
3020a818f0 | ||
|
|
30177e8d7f | ||
|
|
3ad49838be | ||
|
|
3e480abd44 | ||
|
|
49f6b28aef | ||
|
|
b81d13b582 | ||
|
|
04eb3cb640 | ||
|
|
0ac75a088a | ||
|
|
cd652a72a1 | ||
|
|
828ff30dbf | ||
|
|
f452fe8a71 | ||
|
|
15e29a3b8a | ||
|
|
5c6e98f5e1 | ||
|
|
ef06073119 | ||
|
|
bca8b0ad85 | ||
|
|
4983b1fa88 | ||
|
|
f6b6d9f0e7 | ||
|
|
12a168df92 | ||
|
|
e06d2012d6 | ||
|
|
faed2448eb | ||
|
|
a80aed54a0 | ||
|
|
3f9c4dfe99 | ||
|
|
3c91f335fc | ||
|
|
1ea4586360 | ||
|
|
45e08b5b60 | ||
|
|
43ce5a5288 | ||
|
|
887315ceda | ||
|
|
30b5c8dd74 | ||
|
|
ef7ef76a59 | ||
|
|
a9834bcc13 | ||
|
|
ec2752464d | ||
|
|
7b6a9b2a0f | ||
|
|
8eda4f0849 | ||
|
|
cde25214ae | ||
|
|
9f1f66776c | ||
|
|
c93b78528d | ||
|
|
e567e61383 | ||
|
|
7c3184d88a | ||
|
|
e6f38657a3 | ||
|
|
ebcd61a9a2 | ||
|
|
179fbfe84f | ||
|
|
79441abff3 | ||
|
|
c3db8cd4ea | ||
|
|
27c58ffd87 | ||
|
|
244249db2b | ||
|
|
33b937da87 | ||
|
|
058834e8a6 | ||
|
|
b134af3727 | ||
|
|
6d2eafb4f1 | ||
|
|
9f618804df | ||
|
|
61a3a62b65 | ||
|
|
ced25dec87 | ||
|
|
60d5f3361a | ||
|
|
c8ee4cf0c9 | ||
|
|
177434e503 | ||
|
|
58b45cde31 | ||
|
|
ff87030894 | ||
|
|
7635adf637 | ||
|
|
ca7a40044c | ||
|
|
ce5be30f1d | ||
|
|
1cb8f077f5 | ||
|
|
61794cf784 | ||
|
|
045b191e4d | ||
|
|
6116f6a4be | ||
|
|
ca7e94a306 | ||
|
|
165be38cfe | ||
|
|
f1fb5fe5e1 | ||
|
|
17554d3a8e | ||
|
|
054ac3939b | ||
|
|
9566c0a6f5 | ||
|
|
b8509ccb69 | ||
|
|
1e043e4faa | ||
|
|
5b1c177f58 | ||
|
|
794de783db | ||
|
|
7f6aa26986 | ||
|
|
fcd809fda5 | ||
|
|
71ff8007fb | ||
|
|
a8261f4f58 | ||
|
|
bb6a6f3664 | ||
|
|
9c6af07d32 | ||
|
|
afc011adbb | ||
|
|
da42c14d35 | ||
|
|
a7438e2026 | ||
|
|
47e5314bb3 | ||
|
|
1978c1da11 | ||
|
|
914c9d0ea3 | ||
|
|
7134aebb7f | ||
|
|
abb32e9ed2 | ||
|
|
2c77e385c5 | ||
|
|
ba0f5ac124 | ||
|
|
c4f17e3f06 | ||
|
|
b802ec252a | ||
|
|
68779caab0 | ||
|
|
5d819114d0 | ||
|
|
46b3937236 | ||
|
|
6803b8cf4a | ||
|
|
bd9c5a176b | ||
|
|
76c1d96c87 | ||
|
|
304af805cb | ||
|
|
027d3af619 | ||
|
|
c612c01ac7 | ||
|
|
cd7855a877 | ||
|
|
cdd81e0bfb | ||
|
|
750a8b8aff | ||
|
|
cd86155878 | ||
|
|
16739c39d6 | ||
|
|
c7971a9829 | ||
|
|
44c4fc4b21 | ||
|
|
6f1c8e3320 | ||
|
|
8f818416ba | ||
|
|
de6858ca48 | ||
|
|
3fd3d2a378 | ||
|
|
706c9125e6 | ||
|
|
5f026b000c | ||
|
|
0b0d036f08 | ||
|
|
6b9017d535 | ||
|
|
5eb47e33ac | ||
|
|
4d31335da0 | ||
|
|
0b5e76a448 | ||
|
|
775268c01a | ||
|
|
b0b1c85047 | ||
|
|
5f08fc6695 | ||
|
|
2de3bdf12b | ||
|
|
3a424c7dc1 | ||
|
|
c3e2b37072 | ||
|
|
65bd11a346 | ||
|
|
e6e7fc539f | ||
|
|
6522d415b7 | ||
|
|
378c66a333 | ||
|
|
07204417a5 | ||
|
|
c9c909cdf9 | ||
|
|
a9f59a4d2f | ||
|
|
1d2513cef5 | ||
|
|
febb797ae2 | ||
|
|
68d279a7c3 | ||
|
|
d2d8b7955c | ||
|
|
2a55fd9c36 | ||
|
|
695d3c0735 | ||
|
|
ce95db469b | ||
|
|
5d187cf80f | ||
|
|
e704ebc224 | ||
|
|
ee36f8981c | ||
|
|
09dd220abf | ||
|
|
15bc2dc3b8 | ||
|
|
1deb74eca9 | ||
|
|
de76ce64ab | ||
|
|
94b4ba33e6 | ||
|
|
7ce8a115f4 | ||
|
|
c036a4bb45 | ||
|
|
aa62f30b05 | ||
|
|
3d967c9812 | ||
|
|
e87e9efb99 | ||
|
|
8c1f6fb4a6 | ||
|
|
df82ed8a00 | ||
|
|
d01e3920ba | ||
|
|
777cd5ea3f | ||
|
|
3b73aea5c0 | ||
|
|
168f7a8173 | ||
|
|
04437e2de2 | ||
|
|
2ec83b2e87 | ||
|
|
90bfaa7b56 | ||
|
|
2ae175abd0 | ||
|
|
e2a84d8f88 | ||
|
|
b6f9cd0c7c | ||
|
|
61b7b90722 | ||
|
|
093c159753 | ||
|
|
32d36c0757 | ||
|
|
94dabebf2b | ||
|
|
8e875d4f7e | ||
|
|
86c383f2cf | ||
|
|
b404d8e79a | ||
|
|
d32b480ef2 | ||
|
|
3654825f27 | ||
|
|
d7231e8a09 | ||
|
|
98161aaf2e | ||
|
|
7a942b16bc | ||
|
|
067719c69b | ||
|
|
f3fce53b91 | ||
|
|
e35903f436 | ||
|
|
64cfe5fdd7 | ||
|
|
dbe586cff8 | ||
|
|
3104733db0 | ||
|
|
9d4bdd1028 | ||
|
|
f8030b1645 | ||
|
|
0a999ceb41 | ||
|
|
64bd9907cb | ||
|
|
580eaf990d | ||
|
|
5ab232a961 | ||
|
|
e596cd7ea4 | ||
|
|
05c47a4daa | ||
|
|
5a8783b5f4 | ||
|
|
08bc171a72 | ||
|
|
7372f5fe08 | ||
|
|
6f032bdd05 | ||
|
|
153d3603d2 | ||
|
|
95261e6907 | ||
|
|
17b344376d | ||
|
|
0ed4e44878 | ||
|
|
b42c1832f0 | ||
|
|
058534ba67 | ||
|
|
204dcd6498 | ||
|
|
2c846c0db9 | ||
|
|
2faeb044e0 | ||
|
|
09c8e4f779 | ||
|
|
6994fa6be8 | ||
|
|
cc7beb7670 | ||
|
|
510653732d | ||
|
|
93e8178d67 | ||
|
|
cebc4864cc | ||
|
|
6ad0449376 | ||
|
|
c33c977326 | ||
|
|
f0299d365a | ||
|
|
6ecdca73f5 | ||
|
|
af6a709b2c | ||
|
|
d5c27450ef | ||
|
|
d10269fb07 | ||
|
|
53d987476e | ||
|
|
8b7866d37f | ||
|
|
bb529729b6 | ||
|
|
b7735d9ba8 | ||
|
|
ce744e2b84 | ||
|
|
631c92da3f | ||
|
|
b7063804e9 | ||
|
|
75d47c8419 | ||
|
|
114fb05e80 | ||
|
|
1fec65b37d | ||
|
|
9498e8f334 | ||
|
|
83b8411929 | ||
|
|
e9accd13b3 | ||
|
|
9e27a19258 | ||
|
|
252f3a5bea | ||
|
|
e0626bb126 | ||
|
|
7ff62c7f40 | ||
|
|
4b07e02acb | ||
|
|
4654d1d9c2 | ||
|
|
ce1f75e8a5 | ||
|
|
4d9aebc758 | ||
|
|
e814368ef3 | ||
|
|
bbbb02500f | ||
|
|
404f255f14 | ||
|
|
7a15e0d38a | ||
|
|
bfe669bdd9 | ||
|
|
c0553042fd | ||
|
|
af8b02654b | ||
|
|
4779ec91d0 | ||
|
|
14d7f4af0e | ||
|
|
f9888b23dd | ||
|
|
411cdbb00f | ||
|
|
d859f07469 | ||
|
|
c111819093 | ||
|
|
aa8321d13c | ||
|
|
5e3bd972e5 | ||
|
|
ad39a04fff | ||
|
|
9a97e84296 | ||
|
|
1b7b0dcb13 | ||
|
|
d365a5060b | ||
|
|
b69589394a | ||
|
|
00f5791766 | ||
|
|
38cab2eda7 | ||
|
|
0db4d6e4e0 | ||
|
|
549712962f | ||
|
|
34b7002faf | ||
|
|
0e6f47b23c | ||
|
|
a372a89b5e | ||
|
|
239847aee7 | ||
|
|
813249c6a7 | ||
|
|
293ab28bce | ||
|
|
98e73cdec5 | ||
|
|
6d34bb9d25 | ||
|
|
479a5e4da9 | ||
|
|
4829454877 | ||
|
|
28664f6387 | ||
|
|
1a08a23a9c | ||
|
|
16f344ff1b | ||
|
|
693ce0e2e8 | ||
|
|
e6f533ea65 | ||
|
|
fcc21d63b0 | ||
|
|
afc0ffcb67 | ||
|
|
9ffb9840e1 | ||
|
|
4766ccf1b6 | ||
|
|
16b75c80a3 | ||
|
|
880f063046 | ||
|
|
723c11b886 | ||
|
|
5e074b1cf7 | ||
|
|
71d2fee36e | ||
|
|
7dc701464f | ||
|
|
fd876ef90f | ||
|
|
0597852178 | ||
|
|
81b1333091 | ||
|
|
7baebd79a6 | ||
|
|
951d0e30ae | ||
|
|
711e172769 | ||
|
|
faa60f0ea1 | ||
|
|
99d81c4329 | ||
|
|
17904326f3 | ||
|
|
5ee74f39d8 | ||
|
|
72f898ed60 | ||
|
|
157eab5bac | ||
|
|
e1b0d0a2ad | ||
|
|
2c050ba031 | ||
|
|
41518b16b4 | ||
|
|
72a16dc95f | ||
|
|
3404c64f55 | ||
|
|
b9015422f8 | ||
|
|
a7441b968d | ||
|
|
2d44be31f7 | ||
|
|
c2cf25bb2b | ||
|
|
7c4c53dcb0 | ||
|
|
aceb3b17c8 | ||
|
|
adfcfdb1de | ||
|
|
da329723bc | ||
|
|
63eb53fa06 | ||
|
|
d32c824515 | ||
|
|
e9ee8c481c | ||
|
|
6d78e52605 | ||
|
|
90136a5562 | ||
|
|
1592767c8c | ||
|
|
afa6ce2113 | ||
|
|
50e6e414ee | ||
|
|
ba9b8edcdc | ||
|
|
d7a927475c | ||
|
|
afe210343f | ||
|
|
4e293daf62 | ||
|
|
f9d7fdc516 | ||
|
|
6a04f3955c | ||
|
|
dce3b1780c | ||
|
|
f47f3e9db6 | ||
|
|
4ac74acaf7 | ||
|
|
cf7588c288 | ||
|
|
ec7bdf4000 | ||
|
|
51cd97f782 | ||
|
|
a16f2f096d | ||
|
|
4e92f14551 | ||
|
|
8f6cc9ff44 | ||
|
|
f885df5c67 | ||
|
|
0ccb110e36 | ||
|
|
2c238dca9b | ||
|
|
3e0aa53fca | ||
|
|
12b4e44296 | ||
|
|
9a2cf4aefe | ||
|
|
0e2a116e0a | ||
|
|
7bf30eb54a | ||
|
|
8dda8c8ff3 | ||
|
|
988fdb22be | ||
|
|
1dd2c8fb4d | ||
|
|
2b39384b28 | ||
|
|
28d1275023 | ||
|
|
979181fc3b | ||
|
|
b374b88ad5 | ||
|
|
6643c19a20 | ||
|
|
7460874c81 | ||
|
|
13dd7511f6 | ||
|
|
f153d251c8 | ||
|
|
3442ace981 | ||
|
|
547cebf5a9 | ||
|
|
7a24d22bc6 | ||
|
|
8f5728afe4 | ||
|
|
41b5ac2c61 | ||
|
|
694ca3bf25 | ||
|
|
674d314b55 | ||
|
|
08a35cc5d1 | ||
|
|
176e5db4d9 | ||
|
|
2535a9ebf9 | ||
|
|
8ff99ee925 | ||
|
|
abc8218487 | ||
|
|
e4765750c3 | ||
|
|
02cddf556b | ||
|
|
e1e6d3c72d | ||
|
|
b401a16002 | ||
|
|
523b0ce295 | ||
|
|
abb06726f0 | ||
|
|
d9190e9418 | ||
|
|
9fe3761eca | ||
|
|
51824afba6 | ||
|
|
160a49ad5f | ||
|
|
9d4907d77e | ||
|
|
53d30e0503 | ||
|
|
9609a2fd5d | ||
|
|
66cf0efcb9 | ||
|
|
0129b9df31 | ||
|
|
a7a5521be1 | ||
|
|
f7f7211ca2 | ||
|
|
8c921a6ed5 | ||
|
|
f14ab870f7 | ||
|
|
26e81ffdb6 | ||
|
|
598a88203e | ||
|
|
914d02e754 | ||
|
|
5cf30f391b | ||
|
|
8de00cad76 | ||
|
|
e4c58f2f4e | ||
|
|
063dba30b6 | ||
|
|
01fa9287a1 | ||
|
|
008067fccb | ||
|
|
091301e945 | ||
|
|
145f4f3265 | ||
|
|
36d4e8c948 | ||
|
|
63de847a57 | ||
|
|
b3e1b7c902 | ||
|
|
2dbc235631 | ||
|
|
4d68b48367 | ||
|
|
65e63e2b2d | ||
|
|
58071e1de1 | ||
|
|
5009ef479f | ||
|
|
e5e9357649 | ||
|
|
a577474772 | ||
|
|
e960a09153 | ||
|
|
13d50f59c3 | ||
|
|
ed4c8475e9 | ||
|
|
2338bf4e15 | ||
|
|
267aa7ee63 | ||
|
|
3df7dbc769 | ||
|
|
5f12ab7e85 | ||
|
|
ac0adc5f95 | ||
|
|
208b702065 | ||
|
|
7e61fbfbac | ||
|
|
0591549727 | ||
|
|
a0833580f8 | ||
|
|
c622b60215 | ||
|
|
c228cf9072 | ||
|
|
4c68dd4904 | ||
|
|
32fde582fc | ||
|
|
2bf2509df7 | ||
|
|
07042189c8 | ||
|
|
d251c94638 | ||
|
|
b4119087fb | ||
|
|
e3959e80fb | ||
|
|
0495a2344c | ||
|
|
c781ec5a4f | ||
|
|
a58566735f | ||
|
|
b37e5c25c3 | ||
|
|
63a937a45b | ||
|
|
c920471c0c | ||
|
|
c4863ee09b | ||
|
|
c0b85c454e | ||
|
|
763a49a4d3 | ||
|
|
0e1540873c | ||
|
|
39dcc636ca | ||
|
|
342778c56e | ||
|
|
fd524891aa | ||
|
|
48cb60020c | ||
|
|
d502c592f7 | ||
|
|
e4377436a7 | ||
|
|
eb44c1271e | ||
|
|
20953c2dfc | ||
|
|
4c96a71124 | ||
|
|
295afdc874 | ||
|
|
a66280ce7b | ||
|
|
ce1ea1c5c5 |
76
.github/workflows/dotnet-desktop.yml
vendored
76
.github/workflows/dotnet-desktop.yml
vendored
@@ -1,57 +1,91 @@
|
||||
name: Build and Release WinForms
|
||||
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
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref_name }}
|
||||
release_name: Release ${{ github.ref_name }}
|
||||
tag_name: ${{ env.VERSION }}
|
||||
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:
|
||||
|
||||
191
CHANGELOG.md
Normal file
191
CHANGELOG.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v0.12.17
|
||||
|
||||
- 动画边界检测的帧率提高到100帧每秒
|
||||
|
||||
## v0.12.16
|
||||
|
||||
- 导出多个时允许自动时长
|
||||
|
||||
## v0.12.15
|
||||
|
||||
- 修复附件类型枚举量字符串大小写问题
|
||||
|
||||
## v0.12.14
|
||||
|
||||
- 修复 v38 文件读取的小 bug
|
||||
|
||||
## v0.12.13
|
||||
|
||||
- 导出文件名增加额外的随机字符串
|
||||
|
||||
## v0.12.12
|
||||
|
||||
- 修复 2.1 版本遗漏的 SkinnedMeshAttachment 附件渲染
|
||||
|
||||
## v0.12.11
|
||||
|
||||
- 修复可能的闪退错误
|
||||
|
||||
## v0.12.10
|
||||
|
||||
- 增加纹理全局加载选项
|
||||
|
||||
## v0.12.9
|
||||
|
||||
- 修复由于未调用 UpdateCache 导致的约束 bug
|
||||
|
||||
## v0.12.8
|
||||
|
||||
- 增加英语界面文本
|
||||
- 增加 4.2 版本格式转换
|
||||
- 修改格式转换中一些问题和编码范式
|
||||
|
||||
## v0.12.7
|
||||
|
||||
- 修复一些问题
|
||||
|
||||
## v0.12.6
|
||||
|
||||
- 增加全屏预览
|
||||
- 增加桌面投影 (实验性功能)
|
||||
- 增加预览画面背景色设置
|
||||
- 增加分辨率和颜色预设列表
|
||||
- 皮肤面板显示 default
|
||||
|
||||
## v0.12.5
|
||||
|
||||
- 增加插槽属性面板
|
||||
- 修改皮肤属性面板设置方式为True/False
|
||||
|
||||
## v0.12.4
|
||||
|
||||
- 增加导出自动分辨率参数
|
||||
- 增加导出边缘和填充参数
|
||||
- 增加导出内容溢出参数
|
||||
- 支持3.7及以下版本多皮肤功能
|
||||
- 增加3.8版本的骨骼文件二进制和文本格式互转
|
||||
- 增加格式转换输出文件夹参数
|
||||
- 修改打开对话框的默认文件后缀筛选为所有类型
|
||||
|
||||
## v0.12.3
|
||||
|
||||
- 增加按住 ctrl 缩放选中模型
|
||||
- 增加对骨骼/网格/剪裁的调试渲染
|
||||
- 换回以前的上下参数面板布局
|
||||
- 修改窗口缩放模式为 Font -> Dpi
|
||||
- 修复部分问题
|
||||
|
||||
## v0.12.2
|
||||
|
||||
- 模型参数分标签显示
|
||||
- 皮肤/动画列表使用右键菜单进行增删
|
||||
- 标题栏显示版本号
|
||||
- 增加 webp 和 avif 动图格式
|
||||
- 增加导出参数缓存
|
||||
- 动图默认帧率修改为 24 帧
|
||||
- 增加保留最后一帧参数
|
||||
|
||||
## v0.12.1
|
||||
|
||||
- 优化使用体验, 提供初始皮肤/动画空位
|
||||
- 修复预览画面分辨率调整时父容器尺寸获取错误
|
||||
|
||||
## v0.12.0
|
||||
|
||||
- 支持皮肤列表 (仅 3.8.x 及以上支持)
|
||||
- 支持多轨道动画
|
||||
- 动画和皮肤列表多选时改为取并集
|
||||
- 修复导出时没有正确处理预乘像素的问题
|
||||
|
||||
## v0.11.5
|
||||
|
||||
- 导出格式全面支持
|
||||
- 修复预览图不显示的问题
|
||||
- 优化列表卡顿问题
|
||||
- 模型列表增加数量显示
|
||||
|
||||
## v0.11.4
|
||||
|
||||
- 增加 MP4 导出格式
|
||||
- 增加导出背景颜色参数
|
||||
- 增加日志输出 FFMpeg 参数字符串
|
||||
- 增加导出时任务栏图标执行动效
|
||||
- 修复预览面板移动模型时物理效果不同步的问题
|
||||
- 优化部分使用体验
|
||||
|
||||
## v0.11.3
|
||||
|
||||
- 增加模型隐藏设置属性
|
||||
- 加宽面板分割条 (4 -> 8 像素)
|
||||
- 优化属性面板分组显示
|
||||
- 增加调试纹理
|
||||
|
||||
## v0.11.2
|
||||
|
||||
- 增加皮肤切换
|
||||
- 优化模型缩放实现
|
||||
- 修复部分情况纹理加载异常
|
||||
|
||||
## v0.11.1
|
||||
|
||||
- 增加 GIF 导出格式
|
||||
- 增加逐个导出时可选自动时长
|
||||
- 优化使用体验
|
||||
|
||||
## v0.11.0
|
||||
|
||||
- 完成导出系统, 支持完整的单帧和帧序列导出功能
|
||||
- 预览画面增加快进功能
|
||||
|
||||
## v0.10.9
|
||||
|
||||
- 预览图导出增加名称后缀参数
|
||||
|
||||
## v0.10.8
|
||||
|
||||
- 完善预览图导出
|
||||
- 优化骨骼文件选择
|
||||
|
||||
## v0.10.7
|
||||
|
||||
- 增加仅导出选中
|
||||
- 增加模型调试属性
|
||||
|
||||
## v0.10.6
|
||||
|
||||
- 增加文件夹检测
|
||||
- 增加从剪贴板添加(可复制本地文件/文件夹直接打开)
|
||||
- 修复预览图导致的批量添加可能卡死
|
||||
|
||||
## v0.10.5
|
||||
|
||||
- 修复一些问题
|
||||
|
||||
## v0.10.4
|
||||
|
||||
- 修复一些问题
|
||||
|
||||
## v0.10.3
|
||||
|
||||
- 增加自动版本检测
|
||||
- 增加文件拖放打开
|
||||
|
||||
## v0.10.2
|
||||
|
||||
- 增加列表右键菜单快捷键
|
||||
- 增加预览缩略图复制
|
||||
- 增加列表视图切换
|
||||
|
||||
## v0.10.1
|
||||
|
||||
- 增加列表预览图
|
||||
- 增加列表预览图导出
|
||||
|
||||
## v0.10.0
|
||||
|
||||
- 增加了画面和列表的选择联动,并删除了预览画面显示包围盒选项
|
||||
- 增加了骨骼文件格式转换功能,目前仅支持部分版本的不完整功能
|
||||
- 优化了部分使用体验
|
||||
|
||||
126
README.en.md
126
README.en.md
@@ -1,67 +1,111 @@
|
||||
# SpineViewer
|
||||
# [SpineViewer](https://github.com/ww-rm/SpineViewer)
|
||||
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
|
||||
[中文](README.md) | [English](README.en.md)
|
||||
|
||||
A simple and user-friendly Spine file viewer and exporter.
|
||||
A *WYSIWYG* Spine file viewer & exporter.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Download the zip package from the [Releases](https://github.com/ww-rm/SpineViewer/releases) page.
|
||||
|
||||
The application requires the [.NET Desktop Runtime 8.0.x](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).
|
||||
|
||||
Alternatively, you can download the zip package with the `SelfContained` suffix, which can run independently.
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- Supports viewing Spine files of different versions:
|
||||
- [x] `v3.6.x`
|
||||
- [x] `v3.7.x`
|
||||
- [x] `v3.8.x`
|
||||
- [x] `v4.0.x`
|
||||
- [x] `v4.1.x`
|
||||
- [x] `v4.2.x`
|
||||
- [ ] `v4.3.x`
|
||||
- Supports animation preview for multi-skeleton files
|
||||
- Allows independent parameter settings for each skeleton
|
||||
- Supports exporting animation as PNG frame sequences
|
||||
- Provides export settings such as zoom and rotation
|
||||
- More features coming soon...
|
||||
- Supports multiple Spine file versions
|
||||
- Drag & drop or copy/paste to open files in batch
|
||||
- List-based skeleton view with render layer management
|
||||
- Multi-select list to batch-adjust skeleton parameters
|
||||
- Multi-track animation support
|
||||
- Skin / custom slot attachment configuration
|
||||
- Debug rendering mode
|
||||
- Fullscreen preview
|
||||
- Export to single-frame image, animated GIF/WebP/AVIF, video formats
|
||||
- Batch export at multiple resolutions
|
||||
- Custom FFmpeg export parameters
|
||||
- …and more
|
||||
|
||||
### Spine Version Support
|
||||
|
||||
| Version | View & Export | Format Conversion | Version Conversion |
|
||||
| :------: | :-----------: | :---------------: | :----------------: |
|
||||
| `2.1.x` | :white_check_mark: | | |
|
||||
| `3.6.x` | :white_check_mark: | | |
|
||||
| `3.7.x` | :white_check_mark: | | |
|
||||
| `3.8.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.0.x` | :white_check_mark: | | |
|
||||
| `4.1.x` | :white_check_mark: | | |
|
||||
| `4.2.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.3.x` | | | |
|
||||
|
||||
More versions coming soon 🚀🚀🚀
|
||||
|
||||
### Supported Export Formats
|
||||
|
||||
| Export Format | Use Case |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| Single Frame | Generate high‑resolution still images; pick any frame manually. |
|
||||
| Frame Sequence (PNG) | Lossless PNG sequences with alpha channel preserved. |
|
||||
| GIF / WebP / AVIF | Perfect for quick animated previews. |
|
||||
| MP4 | The most widely compatible video format. |
|
||||
| WebM | Browser‑friendly streaming with optional transparency. |
|
||||
| MKV / MOV | For those who like to tinker. |
|
||||
| Custom FFmpeg Command | Use any FFmpeg arguments for complex, tailored export workflows. |
|
||||
|
||||
## Installation
|
||||
|
||||
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
|
||||
|
||||
Use the **File** menu to select **Open** or **Batch Open** to import skeleton files.
|
||||
You can import Spine skeletons in three ways:
|
||||
|
||||
### Adjusting Skeletons
|
||||
- Drag & drop or paste skeleton files or folders onto the model list.
|
||||
- Use **File > Open** to batch‑open multiple skeleton files.
|
||||
- Use **File > Open Single Model** to open one at a time.
|
||||
|
||||
Select one or more items in the **Model List** to display adjustable parameters in the **Model Parameters** panel.
|
||||
### Adjusting Content
|
||||
|
||||
Right-clicking in the **Model List** allows you to add, delete, or adjust list items. You can also drag items with the left mouse button to rearrange them.
|
||||
- Right‑click menu and keyboard shortcuts are available in the model list. You can multi‑select to adjust parameters in batch.
|
||||
- In the preview pane, you can also use mouse controls:
|
||||
- **Left‑click & drag** to move a model; hold **Ctrl** to multi‑select (synced with the list).
|
||||
- **Right‑click & drag** to pan the entire scene.
|
||||
- **Mouse wheel** to zoom; hold **Ctrl** to zoom all selected models proportionally.
|
||||
- **“Render Selected Only”** mode shows only the selected models in preview; use the list to change selection.
|
||||
|
||||
### Adjusting the View
|
||||
Below the preview, playback controls let you scrub through the timeline like a basic player.
|
||||
|
||||
Mouse operations supported in the **Preview** window:
|
||||
### Exporting Content
|
||||
|
||||
- Left-click to drag the skeleton
|
||||
- Right-click to drag the view
|
||||
- Scroll wheel to zoom in/out
|
||||
Exports follow the “what you see is what you get” principle—your real‑time preview is exactly what gets exported.
|
||||
|
||||
Additionally, you can adjust export and preview parameters through the **View Parameters** panel.
|
||||
Key export options:
|
||||
|
||||
In the **Functions** menu, you can reset and synchronize the animation time for all skeletons.
|
||||
- **Render Selected Only**: includes only the selected models in both preview and export.
|
||||
- **Output Folder**: if unspecified, exports go into each model’s source folder; otherwise, everything exports to the chosen folder.
|
||||
- **Export Single**: by default, each model is exported separately; enable this to render all selected models together into a single output.
|
||||
- **Auto Resolution**: ignores preview resolution and viewport size—exports at the content’s actual bounds; for animations, matches the full animation area.
|
||||
|
||||
### Exporting Animations
|
||||
## More
|
||||
|
||||
Select **Export** from the **File** menu to export all loaded skeleton animations as PNG frame sequences, based on the current preview settings.
|
||||
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).
|
||||
|
||||
You can view the full duration of each animation in the **Model Parameters** of each skeleton.
|
||||
## Acknowledgements
|
||||
|
||||
- [spine-runtimes](https://github.com/EsotericSoftware/spine-runtimes)
|
||||
- [SFML.Net](https://github.com/SFML/SFML.Net)
|
||||
- [FFMpegCore](https://github.com/rosenbjerg/FFMpegCore)
|
||||
|
||||
---
|
||||
|
||||
*If you find this project helpful, 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!
|
||||
|
||||
[](https://starchart.cc/ww-rm/SpineViewer)
|
||||
|
||||
112
README.md
112
README.md
@@ -1,12 +1,56 @@
|
||||
# SpineViewer
|
||||
# [SpineViewer](https://github.com/ww-rm/SpineViewer)
|
||||
|
||||
[](https://github.com/ww-rm/SpineViewer/actions/workflows/dotnet-desktop.yml)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
[](https://github.com/ww-rm/SpineViewer/releases)
|
||||
|
||||
[中文](README.md) | [English](README.en.md)
|
||||
|
||||
一个简单好用的 Spine 文件查看&导出程序.
|
||||
*所见即所得* 的 Spine 文件查看&导出程序.
|
||||
|
||||

|
||||

|
||||
|
||||
---
|
||||
## 功能
|
||||
|
||||
- 支持多版本 spine 文件
|
||||
- 支持拖拽/复制粘贴批量打开文件
|
||||
- 支持列表式多骨骼查看和渲染层级管理
|
||||
- 支持列表多选批量设置骨骼参数
|
||||
- 支持多轨道动画设置
|
||||
- 支持皮肤/自定义插槽附件设置
|
||||
- 支持调试渲染
|
||||
- 支持全屏预览
|
||||
- 支持单帧/动图/视频文件导出
|
||||
- 支持自动分辨率批量导出
|
||||
- 支持 FFmpeg 自定义导出
|
||||
- ...
|
||||
|
||||
### Spine 版本支持
|
||||
|
||||
| 版本 | 查看&导出 | 格式转换 | 版本转换 |
|
||||
| :---: | :---: | :---: | :---: |
|
||||
| `2.1.x` | :white_check_mark: | | |
|
||||
| `3.6.x` | :white_check_mark: | | |
|
||||
| `3.7.x` | :white_check_mark: | | |
|
||||
| `3.8.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.0.x` | :white_check_mark: | | |
|
||||
| `4.1.x` | :white_check_mark: | | |
|
||||
| `4.2.x` | :white_check_mark: | :white_check_mark: | |
|
||||
| `4.3.x` | | | |
|
||||
|
||||
更多版本正在施工 :rocket: :rocket: :rocket:
|
||||
|
||||
### 导出格式支持
|
||||
|
||||
| 导出格式 | 适用场景 |
|
||||
| --- | --- |
|
||||
| 单帧画面 | 支持生成高清模型画面图像, 可手动调节需要的一帧. |
|
||||
| 帧序列 | 支持 PNG 格式帧序列, 可保留透明通道且无损压缩. |
|
||||
| GIF/WebP/AVIF | 适合生成预览动图. |
|
||||
| MP4 | 最常见的视频格式, 兼容性最好. |
|
||||
| WebM | 适合浏览器在线播放格式, 支持透明背景. |
|
||||
| MKV/MOV | 适合折腾. |
|
||||
| 自定义导出 | 除上述预设方案, 支持提供任意 FFmpeg 参数进行导出, 满足自定义复杂需求. |
|
||||
|
||||
## 安装
|
||||
|
||||
@@ -16,52 +60,54 @@
|
||||
|
||||
也可以下载带有 `SelfContained` 后缀的压缩包, 可以独立运行.
|
||||
|
||||
## 功能
|
||||
|
||||
- 支持不同版本 Spine 查看
|
||||
- [x] `v3.6.x`
|
||||
- [x] `v3.7.x`
|
||||
- [x] `v3.8.x`
|
||||
- [x] `v4.0.x`
|
||||
- [x] `v4.1.x`
|
||||
- [x] `v4.2.x`
|
||||
- [ ] `v4.3.x`
|
||||
- 支持多骨骼文件动画预览
|
||||
- 支持每个骨骼独立参数设置
|
||||
- 支持动画PNG帧序列导出
|
||||
- 支持缩放旋转等导出画面设置
|
||||
- Coming soon...
|
||||
导出 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 种方式导入骨骼文件:
|
||||
|
||||
### 骨骼调整
|
||||
- 拖放/粘贴需要导入的骨骼文件/目录到模型列表
|
||||
- 从文件菜单里批量打开骨骼文件
|
||||
- 从文件菜单选择单个模型打开
|
||||
|
||||
在**模型列表**中选择一项或多项, 将会在**模型参数**面板显示可供调节的参数.
|
||||
### 内容调整
|
||||
|
||||
**模型列表**右键菜单可以对列表项进行增删调整, 也可以使用鼠标左键拖动调整顺序.
|
||||
模型列表支持右键菜单以及部分快捷键, 并且可以多选进行模型参数的批量调整.
|
||||
|
||||
### 画面调整
|
||||
预览画面除了使用面板进行参数设置外, 支持部分鼠标动作:
|
||||
|
||||
**预览画面**支持的鼠标操作:
|
||||
- 左键可以选择和拖拽模型, 按下 `Ctrl` 键可以实现多选, 与左侧列表选择是联动的.
|
||||
- 右键对整体画面进行拖动.
|
||||
- 滚轮进行画面缩放, 按住 `Ctrl` 可以对选中的模型进行批量缩放.
|
||||
- 仅渲染选中模式, 在该模式下, 预览画面仅包含被选中的模型, 并且只能通过左侧列表改变选中状态.
|
||||
|
||||
- 左键可以对骨骼进行拖动
|
||||
- 右键对画面进行拖动
|
||||
- 滚轮进行画面缩放
|
||||
预览画面下方按钮支持对画面时间进行调整, 可以当作一个简易的播放器.
|
||||
|
||||
除此之外, 也可以通过**画面参数**面板调节导出和预览时的画面参数.
|
||||
### 内容导出
|
||||
|
||||
在**功能**菜单中, 可以重置同步所有骨骼动画时间.
|
||||
导出遵循 "所见即所得" 原则, 即实时预览的画面就是你导出的画面.
|
||||
|
||||
### 动画导出
|
||||
导出有以下几个关键参数:
|
||||
|
||||
**文件**菜单中选择**导出**可以将目前加载的所有骨骼动画按照预览时的画面进行PNG帧序列导出.
|
||||
- 仅渲染选中. 这个参数不仅影响预览模式, 也影响导出, 如果仅渲染选中, 那么在导出时只有被选中的模型会被考虑, 忽略其他模型.
|
||||
- 输出文件夹. 这个参数某些时候可选, 当不提供时, 则将输出产物输出到每个模型各自的模型文件夹, 否则输出产物全部输出到提供的输出文件夹.
|
||||
- 导出单个. 默认是每个模型独立导出, 即对模型列表进行批量操作, 如果选择仅导出单个, 那么被导出的所有模型将在同一个画面上被渲染, 输出产物只有一份.
|
||||
- 自动分辨率. 该模式会忽略预览画面的分辨率和视区参数, 导出产物的分辨率与被导出内容的实际大小一致, 如果是动图或者视频则会与完整显示动画的必需大小一致.
|
||||
|
||||
可以在每个骨骼的**模型参数**中查看动画完整时长.
|
||||
### 更多
|
||||
|
||||
更为详细的使用方法和说明见 [Wiki](https://github.com/ww-rm/SpineViewer/wiki), 有使用上的问题或者 BUG 可以提个 [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)
|
||||
- [FFMpegCore](https://github.com/rosenbjerg/FFMpegCore)
|
||||
|
||||
---
|
||||
|
||||
*如果你觉得这个项目不错请给个 :star:, 并分享给更多人知道! :)*
|
||||
|
||||
[](https://starchart.cc/ww-rm/SpineViewer)
|
||||
|
||||
723
SpineRuntimes/SpineRuntime21/Animation.cs
Normal file
723
SpineRuntimes/SpineRuntime21/Animation.cs
Normal file
@@ -0,0 +1,723 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class Animation {
|
||||
internal List<Timeline> timelines;
|
||||
internal float duration;
|
||||
internal String name;
|
||||
|
||||
public String Name { get { return name; } }
|
||||
public List<Timeline> Timelines { get { return timelines; } set { timelines = value; } }
|
||||
public float Duration { get { return duration; } set { duration = value; } }
|
||||
|
||||
public Animation (String name, List<Timeline> timelines, float duration) {
|
||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||
if (timelines == null) throw new ArgumentNullException("timelines cannot be null.");
|
||||
this.name = name;
|
||||
this.timelines = timelines;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
/// <summary>Poses the skeleton at the specified time for this animation.</summary>
|
||||
/// <param name="lastTime">The last time the animation was applied.</param>
|
||||
/// <param name="events">Any triggered events are added.</param>
|
||||
public void Apply (Skeleton skeleton, float lastTime, float time, bool loop, List<Event> events) {
|
||||
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
|
||||
|
||||
if (loop && duration != 0) {
|
||||
time %= duration;
|
||||
lastTime %= duration;
|
||||
}
|
||||
|
||||
List<Timeline> timelines = this.timelines;
|
||||
for (int i = 0, n = timelines.Count; i < n; i++)
|
||||
timelines[i].Apply(skeleton, lastTime, time, events, 1);
|
||||
}
|
||||
|
||||
/// <summary>Poses the skeleton at the specified time for this animation mixed with the current pose.</summary>
|
||||
/// <param name="lastTime">The last time the animation was applied.</param>
|
||||
/// <param name="events">Any triggered events are added.</param>
|
||||
/// <param name="alpha">The amount of this animation that affects the current pose.</param>
|
||||
public void Mix (Skeleton skeleton, float lastTime, float time, bool loop, List<Event> events, float alpha) {
|
||||
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
|
||||
|
||||
if (loop && duration != 0) {
|
||||
time %= duration;
|
||||
lastTime %= duration;
|
||||
}
|
||||
|
||||
List<Timeline> timelines = this.timelines;
|
||||
for (int i = 0, n = timelines.Count; i < n; i++)
|
||||
timelines[i].Apply(skeleton, lastTime, time, events, alpha);
|
||||
}
|
||||
|
||||
/// <param name="target">After the first and before the last entry.</param>
|
||||
internal static int binarySearch (float[] values, float target, int step) {
|
||||
int low = 0;
|
||||
int high = values.Length / step - 2;
|
||||
if (high == 0) return step;
|
||||
int current = (int)((uint)high >> 1);
|
||||
while (true) {
|
||||
if (values[(current + 1) * step] <= target)
|
||||
low = current + 1;
|
||||
else
|
||||
high = current;
|
||||
if (low == high) return (low + 1) * step;
|
||||
current = (int)((uint)(low + high) >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <param name="target">After the first and before the last entry.</param>
|
||||
internal static int binarySearch (float[] values, float target) {
|
||||
int low = 0;
|
||||
int high = values.Length - 2;
|
||||
if (high == 0) return 1;
|
||||
int current = (int)((uint)high >> 1);
|
||||
while (true) {
|
||||
if (values[(current + 1)] <= target)
|
||||
low = current + 1;
|
||||
else
|
||||
high = current;
|
||||
if (low == high) return (low + 1);
|
||||
current = (int)((uint)(low + high) >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
internal static int linearSearch (float[] values, float target, int step) {
|
||||
for (int i = 0, last = values.Length - step; i <= last; i += step)
|
||||
if (values[i] > target) return i;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Timeline {
|
||||
/// <summary>Sets the value(s) for the specified time.</summary>
|
||||
/// <param name="events">May be null to not collect fired events.</param>
|
||||
void Apply (Skeleton skeleton, float lastTime, float time, List<Event> events, float alpha);
|
||||
}
|
||||
|
||||
/// <summary>Base class for frames that use an interpolation bezier curve.</summary>
|
||||
abstract public class CurveTimeline : Timeline {
|
||||
protected const float LINEAR = 0, STEPPED = 1, BEZIER = 2;
|
||||
protected const int BEZIER_SEGMENTS = 10, BEZIER_SIZE = BEZIER_SEGMENTS * 2 - 1;
|
||||
|
||||
private float[] curves; // type, x, y, ...
|
||||
public int FrameCount { get { return curves.Length / BEZIER_SIZE + 1; } }
|
||||
|
||||
public CurveTimeline (int frameCount) {
|
||||
curves = new float[(frameCount - 1) * BEZIER_SIZE];
|
||||
}
|
||||
|
||||
abstract public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha);
|
||||
|
||||
public void SetLinear (int frameIndex) {
|
||||
curves[frameIndex * BEZIER_SIZE] = LINEAR;
|
||||
}
|
||||
|
||||
public void SetStepped (int frameIndex) {
|
||||
curves[frameIndex * BEZIER_SIZE] = STEPPED;
|
||||
}
|
||||
|
||||
/// <summary>Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
|
||||
/// cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
|
||||
/// the difference between the keyframe's values.</summary>
|
||||
public void SetCurve (int frameIndex, float cx1, float cy1, float cx2, float cy2) {
|
||||
float subdiv1 = 1f / BEZIER_SEGMENTS, subdiv2 = subdiv1 * subdiv1, subdiv3 = subdiv2 * subdiv1;
|
||||
float pre1 = 3 * subdiv1, pre2 = 3 * subdiv2, pre4 = 6 * subdiv2, pre5 = 6 * subdiv3;
|
||||
float tmp1x = -cx1 * 2 + cx2, tmp1y = -cy1 * 2 + cy2, tmp2x = (cx1 - cx2) * 3 + 1, tmp2y = (cy1 - cy2) * 3 + 1;
|
||||
float dfx = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv3, dfy = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv3;
|
||||
float ddfx = tmp1x * pre4 + tmp2x * pre5, ddfy = tmp1y * pre4 + tmp2y * pre5;
|
||||
float dddfx = tmp2x * pre5, dddfy = tmp2y * pre5;
|
||||
|
||||
int i = frameIndex * BEZIER_SIZE;
|
||||
float[] curves = this.curves;
|
||||
curves[i++] = BEZIER;
|
||||
|
||||
float x = dfx, y = dfy;
|
||||
for (int n = i + BEZIER_SIZE - 1; i < n; i += 2) {
|
||||
curves[i] = x;
|
||||
curves[i + 1] = y;
|
||||
dfx += ddfx;
|
||||
dfy += ddfy;
|
||||
ddfx += dddfx;
|
||||
ddfy += dddfy;
|
||||
x += dfx;
|
||||
y += dfy;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetCurvePercent (int frameIndex, float percent) {
|
||||
float[] curves = this.curves;
|
||||
int i = frameIndex * BEZIER_SIZE;
|
||||
float type = curves[i];
|
||||
if (type == LINEAR) return percent;
|
||||
if (type == STEPPED) return 0;
|
||||
i++;
|
||||
float x = 0;
|
||||
for (int start = i, n = i + BEZIER_SIZE - 1; i < n; i += 2) {
|
||||
x = curves[i];
|
||||
if (x >= percent) {
|
||||
float prevX, prevY;
|
||||
if (i == start) {
|
||||
prevX = 0;
|
||||
prevY = 0;
|
||||
} else {
|
||||
prevX = curves[i - 2];
|
||||
prevY = curves[i - 1];
|
||||
}
|
||||
return prevY + (curves[i + 1] - prevY) * (percent - prevX) / (x - prevX);
|
||||
}
|
||||
}
|
||||
float y = curves[i - 1];
|
||||
return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1.
|
||||
}
|
||||
public float GetCurveType (int frameIndex) {
|
||||
return curves[frameIndex * BEZIER_SIZE];
|
||||
}
|
||||
}
|
||||
|
||||
public class RotateTimeline : CurveTimeline {
|
||||
protected const int PREV_FRAME_TIME = -2;
|
||||
protected const int FRAME_VALUE = 1;
|
||||
|
||||
internal int boneIndex;
|
||||
internal float[] frames;
|
||||
|
||||
public int BoneIndex { get { return boneIndex; } set { boneIndex = value; } }
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, value, ...
|
||||
|
||||
public RotateTimeline (int frameCount)
|
||||
: base(frameCount) {
|
||||
frames = new float[frameCount << 1];
|
||||
}
|
||||
|
||||
/// <summary>Sets the time and value of the specified keyframe.</summary>
|
||||
public void SetFrame (int frameIndex, float time, float angle) {
|
||||
frameIndex *= 2;
|
||||
frames[frameIndex] = time;
|
||||
frames[frameIndex + 1] = angle;
|
||||
}
|
||||
|
||||
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
Bone bone = skeleton.bones[boneIndex];
|
||||
|
||||
float amount;
|
||||
|
||||
if (time >= frames[frames.Length - 2]) { // Time is after last frame.
|
||||
amount = bone.data.rotation + frames[frames.Length - 1] - bone.rotation;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
bone.rotation += amount * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frameIndex = Animation.binarySearch(frames, time, 2);
|
||||
float prevFrameValue = frames[frameIndex - 1];
|
||||
float frameTime = frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (frames[frameIndex + PREV_FRAME_TIME] - frameTime);
|
||||
percent = GetCurvePercent((frameIndex >> 1) - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
amount = frames[frameIndex + FRAME_VALUE] - prevFrameValue;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
amount = bone.data.rotation + (prevFrameValue + amount * percent) - bone.rotation;
|
||||
while (amount > 180)
|
||||
amount -= 360;
|
||||
while (amount < -180)
|
||||
amount += 360;
|
||||
bone.rotation += amount * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
public class TranslateTimeline : CurveTimeline {
|
||||
protected const int PREV_FRAME_TIME = -3;
|
||||
protected const int FRAME_X = 1;
|
||||
protected const int FRAME_Y = 2;
|
||||
|
||||
internal int boneIndex;
|
||||
internal float[] frames;
|
||||
|
||||
public int BoneIndex { get { return boneIndex; } set { boneIndex = value; } }
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, value, value, ...
|
||||
|
||||
public TranslateTimeline (int frameCount)
|
||||
: base(frameCount) {
|
||||
frames = new float[frameCount * 3];
|
||||
}
|
||||
|
||||
/// <summary>Sets the time and value of the specified keyframe.</summary>
|
||||
public void SetFrame (int frameIndex, float time, float x, float y) {
|
||||
frameIndex *= 3;
|
||||
frames[frameIndex] = time;
|
||||
frames[frameIndex + 1] = x;
|
||||
frames[frameIndex + 2] = y;
|
||||
}
|
||||
|
||||
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
Bone bone = skeleton.bones[boneIndex];
|
||||
|
||||
if (time >= frames[frames.Length - 3]) { // Time is after last frame.
|
||||
bone.x += (bone.data.x + frames[frames.Length - 2] - bone.x) * alpha;
|
||||
bone.y += (bone.data.y + frames[frames.Length - 1] - bone.y) * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frameIndex = Animation.binarySearch(frames, time, 3);
|
||||
float prevFrameX = frames[frameIndex - 2];
|
||||
float prevFrameY = frames[frameIndex - 1];
|
||||
float frameTime = frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (frames[frameIndex + PREV_FRAME_TIME] - frameTime);
|
||||
percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
bone.x += (bone.data.x + prevFrameX + (frames[frameIndex + FRAME_X] - prevFrameX) * percent - bone.x) * alpha;
|
||||
bone.y += (bone.data.y + prevFrameY + (frames[frameIndex + FRAME_Y] - prevFrameY) * percent - bone.y) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
public class ScaleTimeline : TranslateTimeline {
|
||||
public ScaleTimeline (int frameCount)
|
||||
: base(frameCount) {
|
||||
}
|
||||
|
||||
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
Bone bone = skeleton.bones[boneIndex];
|
||||
if (time >= frames[frames.Length - 3]) { // Time is after last frame.
|
||||
bone.scaleX += (bone.data.scaleX * frames[frames.Length - 2] - bone.scaleX) * alpha;
|
||||
bone.scaleY += (bone.data.scaleY * frames[frames.Length - 1] - bone.scaleY) * alpha;
|
||||
return;
|
||||
}
|
||||
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frameIndex = Animation.binarySearch(frames, time, 3);
|
||||
float prevFrameX = frames[frameIndex - 2];
|
||||
float prevFrameY = frames[frameIndex - 1];
|
||||
float frameTime = frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (frames[frameIndex + PREV_FRAME_TIME] - frameTime);
|
||||
percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
bone.scaleX += (bone.data.scaleX * (prevFrameX + (frames[frameIndex + FRAME_X] - prevFrameX) * percent) - bone.scaleX) * alpha;
|
||||
bone.scaleY += (bone.data.scaleY * (prevFrameY + (frames[frameIndex + FRAME_Y] - prevFrameY) * percent) - bone.scaleY) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
public class ColorTimeline : CurveTimeline {
|
||||
protected const int PREV_FRAME_TIME = -5;
|
||||
protected const int FRAME_R = 1;
|
||||
protected const int FRAME_G = 2;
|
||||
protected const int FRAME_B = 3;
|
||||
protected const int FRAME_A = 4;
|
||||
|
||||
internal int slotIndex;
|
||||
internal float[] frames;
|
||||
|
||||
public int SlotIndex { get { return slotIndex; } set { slotIndex = value; } }
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, r, g, b, a, ...
|
||||
|
||||
public ColorTimeline (int frameCount)
|
||||
: base(frameCount) {
|
||||
frames = new float[frameCount * 5];
|
||||
}
|
||||
|
||||
/// <summary>Sets the time and value of the specified keyframe.</summary>
|
||||
public void SetFrame (int frameIndex, float time, float r, float g, float b, float a) {
|
||||
frameIndex *= 5;
|
||||
frames[frameIndex] = time;
|
||||
frames[frameIndex + 1] = r;
|
||||
frames[frameIndex + 2] = g;
|
||||
frames[frameIndex + 3] = b;
|
||||
frames[frameIndex + 4] = a;
|
||||
}
|
||||
|
||||
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
float r, g, b, a;
|
||||
if (time >= frames[frames.Length - 5]) {
|
||||
// Time is after last frame.
|
||||
int i = frames.Length - 1;
|
||||
r = frames[i - 3];
|
||||
g = frames[i - 2];
|
||||
b = frames[i - 1];
|
||||
a = frames[i];
|
||||
} else {
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frameIndex = Animation.binarySearch(frames, time, 5);
|
||||
float prevFrameR = frames[frameIndex - 4];
|
||||
float prevFrameG = frames[frameIndex - 3];
|
||||
float prevFrameB = frames[frameIndex - 2];
|
||||
float prevFrameA = frames[frameIndex - 1];
|
||||
float frameTime = frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (frames[frameIndex + PREV_FRAME_TIME] - frameTime);
|
||||
percent = GetCurvePercent(frameIndex / 5 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
r = prevFrameR + (frames[frameIndex + FRAME_R] - prevFrameR) * percent;
|
||||
g = prevFrameG + (frames[frameIndex + FRAME_G] - prevFrameG) * percent;
|
||||
b = prevFrameB + (frames[frameIndex + FRAME_B] - prevFrameB) * percent;
|
||||
a = prevFrameA + (frames[frameIndex + FRAME_A] - prevFrameA) * percent;
|
||||
}
|
||||
Slot slot = skeleton.slots[slotIndex];
|
||||
if (alpha < 1) {
|
||||
slot.r += (r - slot.r) * alpha;
|
||||
slot.g += (g - slot.g) * alpha;
|
||||
slot.b += (b - slot.b) * alpha;
|
||||
slot.a += (a - slot.a) * alpha;
|
||||
} else {
|
||||
slot.r = r;
|
||||
slot.g = g;
|
||||
slot.b = b;
|
||||
slot.a = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AttachmentTimeline : Timeline {
|
||||
internal int slotIndex;
|
||||
internal float[] frames;
|
||||
private String[] attachmentNames;
|
||||
|
||||
public int SlotIndex { get { return slotIndex; } set { slotIndex = value; } }
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
|
||||
public String[] AttachmentNames { get { return attachmentNames; } set { attachmentNames = value; } }
|
||||
public int FrameCount { get { return frames.Length; } }
|
||||
|
||||
public AttachmentTimeline (int frameCount) {
|
||||
frames = new float[frameCount];
|
||||
attachmentNames = new String[frameCount];
|
||||
}
|
||||
|
||||
/// <summary>Sets the time and value of the specified keyframe.</summary>
|
||||
public void SetFrame (int frameIndex, float time, String attachmentName) {
|
||||
frames[frameIndex] = time;
|
||||
attachmentNames[frameIndex] = attachmentName;
|
||||
}
|
||||
|
||||
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
if (lastTime > time) Apply(skeleton, lastTime, int.MaxValue, null, 0);
|
||||
return;
|
||||
} else if (lastTime > time) //
|
||||
lastTime = -1;
|
||||
|
||||
int frameIndex = (time >= frames[frames.Length - 1] ? frames.Length : Animation.binarySearch(frames, time)) - 1;
|
||||
if (frames[frameIndex] < lastTime) return;
|
||||
|
||||
String attachmentName = attachmentNames[frameIndex];
|
||||
skeleton.slots[slotIndex].Attachment =
|
||||
attachmentName == null ? null : skeleton.GetAttachment(slotIndex, attachmentName);
|
||||
}
|
||||
}
|
||||
|
||||
public class EventTimeline : Timeline {
|
||||
internal float[] frames;
|
||||
private Event[] events;
|
||||
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
|
||||
public Event[] Events { get { return events; } set { events = value; } }
|
||||
public int FrameCount { get { return frames.Length; } }
|
||||
|
||||
public EventTimeline (int frameCount) {
|
||||
frames = new float[frameCount];
|
||||
events = new Event[frameCount];
|
||||
}
|
||||
|
||||
/// <summary>Sets the time and value of the specified keyframe.</summary>
|
||||
public void SetFrame (int frameIndex, float time, Event e) {
|
||||
frames[frameIndex] = time;
|
||||
events[frameIndex] = e;
|
||||
}
|
||||
|
||||
/// <summary>Fires events for frames > lastTime and <= time.</summary>
|
||||
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
if (firedEvents == null) return;
|
||||
float[] frames = this.frames;
|
||||
int frameCount = frames.Length;
|
||||
|
||||
if (lastTime > time) { // Fire events after last time for looped animations.
|
||||
Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha);
|
||||
lastTime = -1f;
|
||||
} else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
|
||||
return;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
int frameIndex;
|
||||
if (lastTime < frames[0])
|
||||
frameIndex = 0;
|
||||
else {
|
||||
frameIndex = Animation.binarySearch(frames, lastTime);
|
||||
float frame = frames[frameIndex];
|
||||
while (frameIndex > 0) { // Fire multiple events with the same frame.
|
||||
if (frames[frameIndex - 1] != frame) break;
|
||||
frameIndex--;
|
||||
}
|
||||
}
|
||||
for (; frameIndex < frameCount && time >= frames[frameIndex]; frameIndex++)
|
||||
firedEvents.Add(events[frameIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
public class DrawOrderTimeline : Timeline {
|
||||
internal float[] frames;
|
||||
private int[][] drawOrders;
|
||||
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
|
||||
public int[][] DrawOrders { get { return drawOrders; } set { drawOrders = value; } }
|
||||
public int FrameCount { get { return frames.Length; } }
|
||||
|
||||
public DrawOrderTimeline (int frameCount) {
|
||||
frames = new float[frameCount];
|
||||
drawOrders = new int[frameCount][];
|
||||
}
|
||||
|
||||
/// <summary>Sets the time and value of the specified keyframe.</summary>
|
||||
/// <param name="drawOrder">May be null to use bind pose draw order.</param>
|
||||
public void SetFrame (int frameIndex, float time, int[] drawOrder) {
|
||||
frames[frameIndex] = time;
|
||||
drawOrders[frameIndex] = drawOrder;
|
||||
}
|
||||
|
||||
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
int frameIndex;
|
||||
if (time >= frames[frames.Length - 1]) // Time is after last frame.
|
||||
frameIndex = frames.Length - 1;
|
||||
else
|
||||
frameIndex = Animation.binarySearch(frames, time) - 1;
|
||||
|
||||
List<Slot> drawOrder = skeleton.drawOrder;
|
||||
List<Slot> slots = skeleton.slots;
|
||||
int[] drawOrderToSetupIndex = drawOrders[frameIndex];
|
||||
if (drawOrderToSetupIndex == null) {
|
||||
drawOrder.Clear();
|
||||
drawOrder.AddRange(slots);
|
||||
} else {
|
||||
for (int i = 0, n = drawOrderToSetupIndex.Length; i < n; i++)
|
||||
drawOrder[i] = slots[drawOrderToSetupIndex[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FFDTimeline : CurveTimeline {
|
||||
internal int slotIndex;
|
||||
internal float[] frames;
|
||||
private float[][] frameVertices;
|
||||
internal Attachment attachment;
|
||||
|
||||
public int SlotIndex { get { return slotIndex; } set { slotIndex = value; } }
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, ...
|
||||
public float[][] Vertices { get { return frameVertices; } set { frameVertices = value; } }
|
||||
public Attachment Attachment { get { return attachment; } set { attachment = value; } }
|
||||
|
||||
public FFDTimeline (int frameCount)
|
||||
: base(frameCount) {
|
||||
frames = new float[frameCount];
|
||||
frameVertices = new float[frameCount][];
|
||||
}
|
||||
|
||||
/// <summary>Sets the time and value of the specified keyframe.</summary>
|
||||
public void SetFrame (int frameIndex, float time, float[] vertices) {
|
||||
frames[frameIndex] = time;
|
||||
frameVertices[frameIndex] = vertices;
|
||||
}
|
||||
|
||||
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
Slot slot = skeleton.slots[slotIndex];
|
||||
if (slot.attachment != attachment) return;
|
||||
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
float[][] frameVertices = this.frameVertices;
|
||||
int vertexCount = frameVertices[0].Length;
|
||||
|
||||
float[] vertices = slot.attachmentVertices;
|
||||
if (vertices.Length < vertexCount) {
|
||||
vertices = new float[vertexCount];
|
||||
slot.attachmentVertices = vertices;
|
||||
}
|
||||
if (vertices.Length != vertexCount) alpha = 1; // Don't mix from uninitialized slot vertices.
|
||||
slot.attachmentVerticesCount = vertexCount;
|
||||
|
||||
if (time >= frames[frames.Length - 1]) { // Time is after last frame.
|
||||
float[] lastVertices = frameVertices[frames.Length - 1];
|
||||
if (alpha < 1) {
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
float vertex = vertices[i];
|
||||
vertices[i] = vertex + (lastVertices[i] - vertex) * alpha;
|
||||
}
|
||||
} else
|
||||
Array.Copy(lastVertices, 0, vertices, 0, vertexCount);
|
||||
return;
|
||||
}
|
||||
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frameIndex = Animation.binarySearch(frames, time);
|
||||
float frameTime = frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (frames[frameIndex - 1] - frameTime);
|
||||
percent = GetCurvePercent(frameIndex - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
float[] prevVertices = frameVertices[frameIndex - 1];
|
||||
float[] nextVertices = frameVertices[frameIndex];
|
||||
|
||||
if (alpha < 1) {
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
float vertex = vertices[i];
|
||||
vertices[i] = vertex + (prev + (nextVertices[i] - prev) * percent - vertex) * alpha;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
vertices[i] = prev + (nextVertices[i] - prev) * percent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class IkConstraintTimeline : CurveTimeline {
|
||||
private const int PREV_FRAME_TIME = -3;
|
||||
private const int PREV_FRAME_MIX = -2;
|
||||
private const int PREV_FRAME_BEND_DIRECTION = -1;
|
||||
private const int FRAME_MIX = 1;
|
||||
|
||||
internal int ikConstraintIndex;
|
||||
internal float[] frames;
|
||||
|
||||
public int IkConstraintIndex { get { return ikConstraintIndex; } set { ikConstraintIndex = value; } }
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, mix, bendDirection, ...
|
||||
|
||||
public IkConstraintTimeline (int frameCount)
|
||||
: base(frameCount) {
|
||||
frames = new float[frameCount * 3];
|
||||
}
|
||||
|
||||
/** Sets the time, mix and bend direction of the specified keyframe. */
|
||||
public void SetFrame (int frameIndex, float time, float mix, int bendDirection) {
|
||||
frameIndex *= 3;
|
||||
frames[frameIndex] = time;
|
||||
frames[frameIndex + 1] = mix;
|
||||
frames[frameIndex + 2] = bendDirection;
|
||||
}
|
||||
|
||||
override public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) return; // Time is before first frame.
|
||||
|
||||
IkConstraint ikConstraint = skeleton.ikConstraints[ikConstraintIndex];
|
||||
|
||||
if (time >= frames[frames.Length - 3]) { // Time is after last frame.
|
||||
ikConstraint.mix += (frames[frames.Length - 2] - ikConstraint.mix) * alpha;
|
||||
ikConstraint.bendDirection = (int)frames[frames.Length - 1];
|
||||
return;
|
||||
}
|
||||
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frameIndex = Animation.binarySearch(frames, time, 3);
|
||||
float prevFrameMix = frames[frameIndex + PREV_FRAME_MIX];
|
||||
float frameTime = frames[frameIndex];
|
||||
float percent = 1 - (time - frameTime) / (frames[frameIndex + PREV_FRAME_TIME] - frameTime);
|
||||
percent = GetCurvePercent(frameIndex / 3 - 1, percent < 0 ? 0 : (percent > 1 ? 1 : percent));
|
||||
|
||||
float mix = prevFrameMix + (frames[frameIndex + FRAME_MIX] - prevFrameMix) * percent;
|
||||
ikConstraint.mix += (mix - ikConstraint.mix) * alpha;
|
||||
ikConstraint.bendDirection = (int)frames[frameIndex + PREV_FRAME_BEND_DIRECTION];
|
||||
}
|
||||
}
|
||||
|
||||
public class FlipXTimeline : Timeline {
|
||||
internal int boneIndex;
|
||||
internal float[] frames;
|
||||
|
||||
public int BoneIndex { get { return boneIndex; } set { boneIndex = value; } }
|
||||
public float[] Frames { get { return frames; } set { frames = value; } } // time, flip, ...
|
||||
public int FrameCount { get { return frames.Length >> 1; } }
|
||||
|
||||
public FlipXTimeline (int frameCount) {
|
||||
frames = new float[frameCount << 1];
|
||||
}
|
||||
|
||||
/// <summary>Sets the time and value of the specified keyframe.</summary>
|
||||
public void SetFrame (int frameIndex, float time, bool flip) {
|
||||
frameIndex *= 2;
|
||||
frames[frameIndex] = time;
|
||||
frames[frameIndex + 1] = flip ? 1 : 0;
|
||||
}
|
||||
|
||||
public void Apply (Skeleton skeleton, float lastTime, float time, List<Event> firedEvents, float alpha) {
|
||||
float[] frames = this.frames;
|
||||
if (time < frames[0]) {
|
||||
if (lastTime > time) Apply(skeleton, lastTime, int.MaxValue, null, 0);
|
||||
return;
|
||||
} else if (lastTime > time) //
|
||||
lastTime = -1;
|
||||
|
||||
int frameIndex = (time >= frames[frames.Length - 2] ? frames.Length : Animation.binarySearch(frames, time, 2)) - 2;
|
||||
if (frames[frameIndex] < lastTime) return;
|
||||
|
||||
SetFlip(skeleton.bones[boneIndex], frames[frameIndex + 1] != 0);
|
||||
}
|
||||
|
||||
virtual protected void SetFlip (Bone bone, bool flip) {
|
||||
bone.flipX = flip;
|
||||
}
|
||||
}
|
||||
|
||||
public class FlipYTimeline : FlipXTimeline {
|
||||
public FlipYTimeline (int frameCount)
|
||||
: base(frameCount) {
|
||||
}
|
||||
|
||||
override protected void SetFlip (Bone bone, bool flip) {
|
||||
bone.flipY = flip;
|
||||
}
|
||||
}
|
||||
}
|
||||
300
SpineRuntimes/SpineRuntime21/AnimationState.cs
Normal file
300
SpineRuntimes/SpineRuntime21/AnimationState.cs
Normal file
@@ -0,0 +1,300 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class AnimationState {
|
||||
private AnimationStateData data;
|
||||
private List<TrackEntry> tracks = new List<TrackEntry>();
|
||||
private List<Event> events = new List<Event>();
|
||||
private float timeScale = 1;
|
||||
|
||||
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 event StartEndDelegate Start;
|
||||
public event StartEndDelegate End;
|
||||
|
||||
public delegate void EventDelegate(AnimationState state, int trackIndex, Event e);
|
||||
public event EventDelegate Event;
|
||||
|
||||
public delegate void CompleteDelegate(AnimationState state, int trackIndex, int loopCount);
|
||||
public event CompleteDelegate Complete;
|
||||
|
||||
public AnimationState (AnimationStateData data) {
|
||||
if (data == null) throw new ArgumentNullException("data cannot be null.");
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void Update (float delta) {
|
||||
delta *= timeScale;
|
||||
for (int i = 0; i < tracks.Count; i++) {
|
||||
TrackEntry current = tracks[i];
|
||||
if (current == null) continue;
|
||||
|
||||
float trackDelta = delta * current.timeScale;
|
||||
float time = current.time + trackDelta;
|
||||
float endTime = current.endTime;
|
||||
|
||||
current.time = time;
|
||||
if (current.previous != null) {
|
||||
current.previous.time += trackDelta;
|
||||
current.mixTime += trackDelta;
|
||||
}
|
||||
|
||||
// Check if completed the animation or a loop iteration.
|
||||
if (current.loop ? (current.lastTime % endTime > time % endTime) : (current.lastTime < endTime && time >= endTime)) {
|
||||
int count = (int)(time / endTime);
|
||||
current.OnComplete(this, i, count);
|
||||
if (Complete != null) Complete(this, i, count);
|
||||
}
|
||||
|
||||
TrackEntry next = current.next;
|
||||
if (next != null) {
|
||||
next.time = current.lastTime - next.delay;
|
||||
if (next.time >= 0) SetCurrent(i, next);
|
||||
} else {
|
||||
// End non-looping animation when it reaches its end time and there is no next entry.
|
||||
if (!current.loop && current.lastTime >= current.endTime) ClearTrack(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Apply (Skeleton skeleton) {
|
||||
List<Event> events = this.events;
|
||||
|
||||
for (int i = 0; i < tracks.Count; i++) {
|
||||
TrackEntry current = tracks[i];
|
||||
if (current == null) continue;
|
||||
|
||||
events.Clear();
|
||||
|
||||
float time = current.time;
|
||||
bool loop = current.loop;
|
||||
if (!loop && time > current.endTime) time = current.endTime;
|
||||
|
||||
TrackEntry previous = current.previous;
|
||||
if (previous == null) {
|
||||
if (current.mix == 1)
|
||||
current.animation.Apply(skeleton, current.lastTime, time, loop, events);
|
||||
else
|
||||
current.animation.Mix(skeleton, current.lastTime, time, loop, events, current.mix);
|
||||
} else {
|
||||
float previousTime = previous.time;
|
||||
if (!previous.loop && previousTime > previous.endTime) previousTime = previous.endTime;
|
||||
previous.animation.Apply(skeleton, previousTime, previousTime, previous.loop, null);
|
||||
|
||||
float alpha = current.mixTime / current.mixDuration * current.mix;
|
||||
if (alpha >= 1) {
|
||||
alpha = 1;
|
||||
current.previous = null;
|
||||
}
|
||||
current.animation.Mix(skeleton, current.lastTime, time, loop, events, alpha);
|
||||
}
|
||||
|
||||
for (int ii = 0, nn = events.Count; ii < nn; ii++) {
|
||||
Event e = events[ii];
|
||||
current.OnEvent(this, i, e);
|
||||
if (Event != null) Event(this, i, e);
|
||||
}
|
||||
|
||||
current.lastTime = current.time;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearTracks () {
|
||||
for (int i = 0, n = tracks.Count; i < n; i++)
|
||||
ClearTrack(i);
|
||||
tracks.Clear();
|
||||
}
|
||||
|
||||
public void ClearTrack (int trackIndex) {
|
||||
if (trackIndex >= tracks.Count) return;
|
||||
TrackEntry current = tracks[trackIndex];
|
||||
if (current == null) return;
|
||||
|
||||
current.OnEnd(this, trackIndex);
|
||||
if (End != null) End(this, trackIndex);
|
||||
|
||||
tracks[trackIndex] = null;
|
||||
}
|
||||
|
||||
private TrackEntry ExpandToIndex (int index) {
|
||||
if (index < tracks.Count) return tracks[index];
|
||||
while (index >= tracks.Count)
|
||||
tracks.Add(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SetCurrent (int index, TrackEntry entry) {
|
||||
TrackEntry current = ExpandToIndex(index);
|
||||
if (current != null) {
|
||||
TrackEntry previous = current.previous;
|
||||
current.previous = null;
|
||||
|
||||
current.OnEnd(this, index);
|
||||
if (End != null) End(this, index);
|
||||
|
||||
entry.mixDuration = data.GetMix(current.animation, entry.animation);
|
||||
if (entry.mixDuration > 0) {
|
||||
entry.mixTime = 0;
|
||||
// If a mix is in progress, mix from the closest animation.
|
||||
if (previous != null && current.mixTime / current.mixDuration < 0.5f)
|
||||
entry.previous = previous;
|
||||
else
|
||||
entry.previous = current;
|
||||
}
|
||||
}
|
||||
|
||||
tracks[index] = entry;
|
||||
|
||||
entry.OnStart(this, index);
|
||||
if (Start != null) Start(this, index);
|
||||
}
|
||||
|
||||
public TrackEntry SetAnimation (int trackIndex, String animationName, bool loop) {
|
||||
Animation animation = data.skeletonData.FindAnimation(animationName);
|
||||
if (animation == null) throw new ArgumentException("Animation not found: " + animationName);
|
||||
return SetAnimation(trackIndex, animation, loop);
|
||||
}
|
||||
|
||||
/// <summary>Set the current animation. Any queued animations are cleared.</summary>
|
||||
public TrackEntry SetAnimation (int trackIndex, Animation animation, bool loop) {
|
||||
if (animation == null) throw new ArgumentException("animation cannot be null.");
|
||||
TrackEntry entry = new TrackEntry();
|
||||
entry.animation = animation;
|
||||
entry.loop = loop;
|
||||
entry.time = 0;
|
||||
entry.endTime = animation.Duration;
|
||||
SetCurrent(trackIndex, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public TrackEntry AddAnimation (int trackIndex, String animationName, bool loop, float delay) {
|
||||
Animation animation = data.skeletonData.FindAnimation(animationName);
|
||||
if (animation == null) throw new ArgumentException("Animation not found: " + animationName);
|
||||
return AddAnimation(trackIndex, animation, loop, delay);
|
||||
}
|
||||
|
||||
/// <summary>Adds an animation to be played delay seconds after the current or last queued animation.</summary>
|
||||
/// <param name="delay">May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay.</param>
|
||||
public TrackEntry AddAnimation (int trackIndex, Animation animation, bool loop, float delay) {
|
||||
if (animation == null) throw new ArgumentException("animation cannot be null.");
|
||||
TrackEntry entry = new TrackEntry();
|
||||
entry.animation = animation;
|
||||
entry.loop = loop;
|
||||
entry.time = 0;
|
||||
entry.endTime = animation.Duration;
|
||||
|
||||
TrackEntry last = ExpandToIndex(trackIndex);
|
||||
if (last != null) {
|
||||
while (last.next != null)
|
||||
last = last.next;
|
||||
last.next = entry;
|
||||
} else
|
||||
tracks[trackIndex] = entry;
|
||||
|
||||
if (delay <= 0) {
|
||||
if (last != null)
|
||||
delay += last.endTime - data.GetMix(last.animation, animation);
|
||||
else
|
||||
delay = 0;
|
||||
}
|
||||
entry.delay = delay;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public TrackEntry GetCurrent (int trackIndex) {
|
||||
if (trackIndex >= tracks.Count) return null;
|
||||
return tracks[trackIndex];
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
for (int i = 0, n = tracks.Count; i < n; i++) {
|
||||
TrackEntry entry = tracks[i];
|
||||
if (entry == null) continue;
|
||||
if (buffer.Length > 0) buffer.Append(", ");
|
||||
buffer.Append(entry.ToString());
|
||||
}
|
||||
if (buffer.Length == 0) return "<none>";
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class TrackEntry {
|
||||
internal TrackEntry next, previous;
|
||||
internal Animation animation;
|
||||
internal bool loop;
|
||||
internal float delay, time, lastTime = -1, endTime, timeScale = 1;
|
||||
internal float mixTime, mixDuration, mix = 1;
|
||||
|
||||
public Animation Animation { get { return animation; } }
|
||||
public float Delay { get { return delay; } set { delay = value; } }
|
||||
public float Time { get { return time; } set { time = value; } }
|
||||
public float LastTime { get { return lastTime; } set { lastTime = value; } }
|
||||
public float EndTime { get { return endTime; } set { endTime = value; } }
|
||||
public float TimeScale { get { return timeScale; } set { timeScale = value; } }
|
||||
public float Mix { get { return mix; } set { mix = value; } }
|
||||
public bool Loop { get { return loop; } set { loop = value; } }
|
||||
|
||||
public event AnimationState.StartEndDelegate Start;
|
||||
public event AnimationState.StartEndDelegate End;
|
||||
public event AnimationState.EventDelegate Event;
|
||||
public event AnimationState.CompleteDelegate Complete;
|
||||
|
||||
internal void OnStart (AnimationState state, int index) {
|
||||
if (Start != null) Start(state, index);
|
||||
}
|
||||
|
||||
internal void OnEnd (AnimationState state, int index) {
|
||||
if (End != null) End(state, index);
|
||||
}
|
||||
|
||||
internal void OnEvent (AnimationState state, int index, Event e) {
|
||||
if (Event != null) Event(state, index, e);
|
||||
}
|
||||
|
||||
internal void OnComplete (AnimationState state, int index, int loopCount) {
|
||||
if (Complete != null) Complete(state, index, loopCount);
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return animation == null ? "<none>" : animation.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
70
SpineRuntimes/SpineRuntime21/AnimationStateData.cs
Normal file
70
SpineRuntimes/SpineRuntime21/AnimationStateData.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class AnimationStateData {
|
||||
internal SkeletonData skeletonData;
|
||||
private Dictionary<KeyValuePair<Animation, Animation>, float> animationToMixTime = new Dictionary<KeyValuePair<Animation, Animation>, float>();
|
||||
internal float defaultMix;
|
||||
|
||||
public SkeletonData SkeletonData { get { return skeletonData; } }
|
||||
public float DefaultMix { get { return defaultMix; } set { defaultMix = value; } }
|
||||
|
||||
public AnimationStateData (SkeletonData skeletonData) {
|
||||
this.skeletonData = skeletonData;
|
||||
}
|
||||
|
||||
public void SetMix (String fromName, String toName, float duration) {
|
||||
Animation from = skeletonData.FindAnimation(fromName);
|
||||
if (from == null) throw new ArgumentException("Animation not found: " + fromName);
|
||||
Animation to = skeletonData.FindAnimation(toName);
|
||||
if (to == null) throw new ArgumentException("Animation not found: " + toName);
|
||||
SetMix(from, to, duration);
|
||||
}
|
||||
|
||||
public void SetMix (Animation from, Animation to, float duration) {
|
||||
if (from == null) throw new ArgumentNullException("from cannot be null.");
|
||||
if (to == null) throw new ArgumentNullException("to cannot be null.");
|
||||
KeyValuePair<Animation, Animation> key = new KeyValuePair<Animation, Animation>(from, to);
|
||||
animationToMixTime.Remove(key);
|
||||
animationToMixTime.Add(key, duration);
|
||||
}
|
||||
|
||||
public float GetMix (Animation from, Animation to) {
|
||||
KeyValuePair<Animation, Animation> key = new KeyValuePair<Animation, Animation>(from, to);
|
||||
float duration;
|
||||
if (animationToMixTime.TryGetValue(key, out duration)) return duration;
|
||||
return defaultMix;
|
||||
}
|
||||
}
|
||||
}
|
||||
288
SpineRuntimes/SpineRuntime21/Atlas.cs
Normal file
288
SpineRuntimes/SpineRuntime21/Atlas.cs
Normal file
@@ -0,0 +1,288 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
#if WINDOWS_STOREAPP
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
#endif
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class Atlas {
|
||||
List<AtlasPage> pages = new List<AtlasPage>();
|
||||
List<AtlasRegion> regions = new List<AtlasRegion>();
|
||||
TextureLoader textureLoader;
|
||||
|
||||
#if WINDOWS_STOREAPP
|
||||
private async Task ReadFile(string path, TextureLoader textureLoader) {
|
||||
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
||||
var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false);
|
||||
using (var reader = new StreamReader(await file.OpenStreamForReadAsync().ConfigureAwait(false))) {
|
||||
try {
|
||||
Load(reader, Path.GetDirectoryName(path), textureLoader);
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Error reading atlas file: " + path, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Atlas(String path, TextureLoader textureLoader) {
|
||||
this.ReadFile(path, textureLoader).Wait();
|
||||
}
|
||||
#else
|
||||
public Atlas (String path, TextureLoader textureLoader) {
|
||||
|
||||
#if WINDOWS_PHONE
|
||||
Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(path);
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
#else
|
||||
using (StreamReader reader = new StreamReader(path)) {
|
||||
#endif
|
||||
try {
|
||||
Load(reader, Path.GetDirectoryName(path), textureLoader);
|
||||
} catch (Exception ex) {
|
||||
throw new Exception("Error reading atlas file: " + path, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public Atlas (TextReader reader, String dir, TextureLoader textureLoader) {
|
||||
Load(reader, dir, textureLoader);
|
||||
}
|
||||
|
||||
public Atlas (List<AtlasPage> pages, List<AtlasRegion> regions) {
|
||||
this.pages = pages;
|
||||
this.regions = regions;
|
||||
this.textureLoader = null;
|
||||
}
|
||||
|
||||
private void Load (TextReader reader, String imagesDir, TextureLoader textureLoader) {
|
||||
if (textureLoader == null) throw new ArgumentNullException("textureLoader cannot be null.");
|
||||
this.textureLoader = textureLoader;
|
||||
|
||||
String[] tuple = new String[4];
|
||||
AtlasPage page = null;
|
||||
while (true) {
|
||||
String line = reader.ReadLine();
|
||||
if (line == null) break;
|
||||
if (line.Trim().Length == 0)
|
||||
page = null;
|
||||
else if (page == null) {
|
||||
page = new AtlasPage();
|
||||
page.name = line;
|
||||
|
||||
if (readTuple(reader, tuple) == 2) { // size is only optional for an atlas packed with an old TexturePacker.
|
||||
page.width = int.Parse(tuple[0]);
|
||||
page.height = int.Parse(tuple[1]);
|
||||
readTuple(reader, tuple);
|
||||
}
|
||||
page.format = (Format)Enum.Parse(typeof(Format), tuple[0], false);
|
||||
|
||||
readTuple(reader, tuple);
|
||||
page.minFilter = (TextureFilter)Enum.Parse(typeof(TextureFilter), tuple[0], false);
|
||||
page.magFilter = (TextureFilter)Enum.Parse(typeof(TextureFilter), tuple[1], false);
|
||||
|
||||
String direction = readValue(reader);
|
||||
page.uWrap = TextureWrap.ClampToEdge;
|
||||
page.vWrap = TextureWrap.ClampToEdge;
|
||||
if (direction == "x")
|
||||
page.uWrap = TextureWrap.Repeat;
|
||||
else if (direction == "y")
|
||||
page.vWrap = TextureWrap.Repeat;
|
||||
else if (direction == "xy")
|
||||
page.uWrap = page.vWrap = TextureWrap.Repeat;
|
||||
|
||||
textureLoader.Load(page, Path.Combine(imagesDir, line));
|
||||
|
||||
pages.Add(page);
|
||||
|
||||
} else {
|
||||
AtlasRegion region = new AtlasRegion();
|
||||
region.name = line;
|
||||
region.page = page;
|
||||
|
||||
region.rotate = Boolean.Parse(readValue(reader));
|
||||
|
||||
readTuple(reader, tuple);
|
||||
int x = int.Parse(tuple[0]);
|
||||
int y = int.Parse(tuple[1]);
|
||||
|
||||
readTuple(reader, tuple);
|
||||
int width = int.Parse(tuple[0]);
|
||||
int height = int.Parse(tuple[1]);
|
||||
|
||||
region.u = x / (float)page.width;
|
||||
region.v = y / (float)page.height;
|
||||
if (region.rotate) {
|
||||
region.u2 = (x + height) / (float)page.width;
|
||||
region.v2 = (y + width) / (float)page.height;
|
||||
} else {
|
||||
region.u2 = (x + width) / (float)page.width;
|
||||
region.v2 = (y + height) / (float)page.height;
|
||||
}
|
||||
region.x = x;
|
||||
region.y = y;
|
||||
region.width = Math.Abs(width);
|
||||
region.height = Math.Abs(height);
|
||||
|
||||
if (readTuple(reader, tuple) == 4) { // split is optional
|
||||
region.splits = new int[] {int.Parse(tuple[0]), int.Parse(tuple[1]),
|
||||
int.Parse(tuple[2]), int.Parse(tuple[3])};
|
||||
|
||||
if (readTuple(reader, tuple) == 4) { // pad is optional, but only present with splits
|
||||
region.pads = new int[] {int.Parse(tuple[0]), int.Parse(tuple[1]),
|
||||
int.Parse(tuple[2]), int.Parse(tuple[3])};
|
||||
|
||||
readTuple(reader, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
region.originalWidth = int.Parse(tuple[0]);
|
||||
region.originalHeight = int.Parse(tuple[1]);
|
||||
|
||||
readTuple(reader, tuple);
|
||||
region.offsetX = int.Parse(tuple[0]);
|
||||
region.offsetY = int.Parse(tuple[1]);
|
||||
|
||||
region.index = int.Parse(readValue(reader));
|
||||
|
||||
regions.Add(region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static String readValue (TextReader reader) {
|
||||
String line = reader.ReadLine();
|
||||
int colon = line.IndexOf(':');
|
||||
if (colon == -1) throw new Exception("Invalid line: " + line);
|
||||
return line.Substring(colon + 1).Trim();
|
||||
}
|
||||
|
||||
/// <summary>Returns the number of tuple values read (1, 2 or 4).</summary>
|
||||
static int readTuple (TextReader reader, String[] tuple) {
|
||||
String line = reader.ReadLine();
|
||||
int colon = line.IndexOf(':');
|
||||
if (colon == -1) throw new Exception("Invalid line: " + line);
|
||||
int i = 0, lastMatch = colon + 1;
|
||||
for (; i < 3; i++) {
|
||||
int comma = line.IndexOf(',', lastMatch);
|
||||
if (comma == -1) break;
|
||||
tuple[i] = line.Substring(lastMatch, comma - lastMatch).Trim();
|
||||
lastMatch = comma + 1;
|
||||
}
|
||||
tuple[i] = line.Substring(lastMatch).Trim();
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
public void FlipV () {
|
||||
for (int i = 0, n = regions.Count; i < n; i++) {
|
||||
AtlasRegion region = regions[i];
|
||||
region.v = 1 - region.v;
|
||||
region.v2 = 1 - region.v2;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns the first region found with the specified name. This method uses string comparison to find the region, so the result
|
||||
/// should be cached rather than calling this method multiple times.</summary>
|
||||
/// <returns>The region, or null.</returns>
|
||||
public AtlasRegion FindRegion (String name) {
|
||||
for (int i = 0, n = regions.Count; i < n; i++)
|
||||
if (regions[i].name == name) return regions[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Dispose () {
|
||||
if (textureLoader == null) return;
|
||||
for (int i = 0, n = pages.Count; i < n; i++)
|
||||
textureLoader.Unload(pages[i].rendererObject);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Format {
|
||||
Alpha,
|
||||
Intensity,
|
||||
LuminanceAlpha,
|
||||
RGB565,
|
||||
RGBA4444,
|
||||
RGB888,
|
||||
RGBA8888
|
||||
}
|
||||
|
||||
public enum TextureFilter {
|
||||
Nearest,
|
||||
Linear,
|
||||
MipMap,
|
||||
MipMapNearestNearest,
|
||||
MipMapLinearNearest,
|
||||
MipMapNearestLinear,
|
||||
MipMapLinearLinear
|
||||
}
|
||||
|
||||
public enum TextureWrap {
|
||||
MirroredRepeat,
|
||||
ClampToEdge,
|
||||
Repeat
|
||||
}
|
||||
|
||||
public class AtlasPage {
|
||||
public String name;
|
||||
public Format format;
|
||||
public TextureFilter minFilter;
|
||||
public TextureFilter magFilter;
|
||||
public TextureWrap uWrap;
|
||||
public TextureWrap vWrap;
|
||||
public Object rendererObject;
|
||||
public int width, height;
|
||||
}
|
||||
|
||||
public class AtlasRegion {
|
||||
public AtlasPage page;
|
||||
public String name;
|
||||
public int x, y, width, height;
|
||||
public float u, v, u2, v2;
|
||||
public float offsetX, offsetY;
|
||||
public int originalWidth, originalHeight;
|
||||
public int index;
|
||||
public bool rotate;
|
||||
public int[] splits;
|
||||
public int[] pads;
|
||||
}
|
||||
|
||||
public interface TextureLoader {
|
||||
void Load (AtlasPage page, String path);
|
||||
void Unload (Object texture);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class AtlasAttachmentLoader : AttachmentLoader {
|
||||
private Atlas[] atlasArray;
|
||||
|
||||
public AtlasAttachmentLoader (params Atlas[] atlasArray) {
|
||||
if (atlasArray == null) throw new ArgumentNullException("atlas array cannot be null.");
|
||||
this.atlasArray = atlasArray;
|
||||
}
|
||||
|
||||
public RegionAttachment NewRegionAttachment (Skin skin, String name, String path) {
|
||||
AtlasRegion region = FindRegion(path);
|
||||
if (region == null) throw new Exception("Region not found in atlas: " + path + " (region attachment: " + name + ")");
|
||||
RegionAttachment attachment = new RegionAttachment(name);
|
||||
attachment.RendererObject = region;
|
||||
attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate);
|
||||
attachment.regionOffsetX = region.offsetX;
|
||||
attachment.regionOffsetY = region.offsetY;
|
||||
attachment.regionWidth = region.width;
|
||||
attachment.regionHeight = region.height;
|
||||
attachment.regionOriginalWidth = region.originalWidth;
|
||||
attachment.regionOriginalHeight = region.originalHeight;
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public MeshAttachment NewMeshAttachment (Skin skin, String name, String path) {
|
||||
AtlasRegion region = FindRegion(path);
|
||||
if (region == null) throw new Exception("Region not found in atlas: " + path + " (mesh attachment: " + name + ")");
|
||||
MeshAttachment attachment = new MeshAttachment(name);
|
||||
attachment.RendererObject = region;
|
||||
attachment.RegionU = region.u;
|
||||
attachment.RegionV = region.v;
|
||||
attachment.RegionU2 = region.u2;
|
||||
attachment.RegionV2 = region.v2;
|
||||
attachment.RegionRotate = region.rotate;
|
||||
attachment.regionOffsetX = region.offsetX;
|
||||
attachment.regionOffsetY = region.offsetY;
|
||||
attachment.regionWidth = region.width;
|
||||
attachment.regionHeight = region.height;
|
||||
attachment.regionOriginalWidth = region.originalWidth;
|
||||
attachment.regionOriginalHeight = region.originalHeight;
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public SkinnedMeshAttachment NewSkinnedMeshAttachment (Skin skin, String name, String path) {
|
||||
AtlasRegion region = FindRegion(path);
|
||||
if (region == null) throw new Exception("Region not found in atlas: " + path + " (skinned mesh attachment: " + name + ")");
|
||||
SkinnedMeshAttachment attachment = new SkinnedMeshAttachment(name);
|
||||
attachment.RendererObject = region;
|
||||
attachment.RegionU = region.u;
|
||||
attachment.RegionV = region.v;
|
||||
attachment.RegionU2 = region.u2;
|
||||
attachment.RegionV2 = region.v2;
|
||||
attachment.RegionRotate = region.rotate;
|
||||
attachment.regionOffsetX = region.offsetX;
|
||||
attachment.regionOffsetY = region.offsetY;
|
||||
attachment.regionWidth = region.width;
|
||||
attachment.regionHeight = region.height;
|
||||
attachment.regionOriginalWidth = region.originalWidth;
|
||||
attachment.regionOriginalHeight = region.originalHeight;
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name) {
|
||||
return new BoundingBoxAttachment(name);
|
||||
}
|
||||
|
||||
public AtlasRegion FindRegion(string name) {
|
||||
AtlasRegion region;
|
||||
|
||||
for (int i = 0; i < atlasArray.Length; i++) {
|
||||
region = atlasArray[i].FindRegion(name);
|
||||
if (region != null)
|
||||
return region;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
SpineRuntimes/SpineRuntime21/Attachments/Attachment.cs
Normal file
46
SpineRuntimes/SpineRuntime21/Attachments/Attachment.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
abstract public class Attachment {
|
||||
public String Name { get; private set; }
|
||||
|
||||
public Attachment (String name) {
|
||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||
Name = name;
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
47
SpineRuntimes/SpineRuntime21/Attachments/AttachmentLoader.cs
Normal file
47
SpineRuntimes/SpineRuntime21/Attachments/AttachmentLoader.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public interface AttachmentLoader {
|
||||
/// <return>May be null to not load any attachment.</return>
|
||||
RegionAttachment NewRegionAttachment (Skin skin, String name, String path);
|
||||
|
||||
/// <return>May be null to not load any attachment.</return>
|
||||
MeshAttachment NewMeshAttachment (Skin skin, String name, String path);
|
||||
|
||||
/// <return>May be null to not load any attachment.</return>
|
||||
SkinnedMeshAttachment NewSkinnedMeshAttachment (Skin skin, String name, String path);
|
||||
|
||||
/// <return>May be null to not load any attachment.</return>
|
||||
BoundingBoxAttachment NewBoundingBoxAttachment (Skin skin, String name);
|
||||
}
|
||||
}
|
||||
35
SpineRuntimes/SpineRuntime21/Attachments/AttachmentType.cs
Normal file
35
SpineRuntimes/SpineRuntime21/Attachments/AttachmentType.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public enum AttachmentType {
|
||||
region, boundingbox, mesh, skinnedmesh
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
/// <summary>Attachment that has a polygon for bounds checking.</summary>
|
||||
public class BoundingBoxAttachment : Attachment {
|
||||
internal float[] vertices;
|
||||
|
||||
public float[] Vertices { get { return vertices; } set { vertices = value; } }
|
||||
|
||||
public BoundingBoxAttachment (string name)
|
||||
: base(name) {
|
||||
}
|
||||
|
||||
/// <param name="worldVertices">Must have at least the same length as this attachment's vertices.</param>
|
||||
public void ComputeWorldVertices (Bone bone, float[] worldVertices) {
|
||||
float x = bone.skeleton.x + bone.worldX, y = bone.skeleton.y + bone.worldY;
|
||||
float m00 = bone.m00;
|
||||
float m01 = bone.m01;
|
||||
float m10 = bone.m10;
|
||||
float m11 = bone.m11;
|
||||
float[] vertices = this.vertices;
|
||||
for (int i = 0, n = vertices.Length; i < n; i += 2) {
|
||||
float px = vertices[i];
|
||||
float py = vertices[i + 1];
|
||||
worldVertices[i] = px * m00 + py * m01 + x;
|
||||
worldVertices[i + 1] = px * m10 + py * m11 + y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
108
SpineRuntimes/SpineRuntime21/Attachments/MeshAttachment.cs
Normal file
108
SpineRuntimes/SpineRuntime21/Attachments/MeshAttachment.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
/// <summary>Attachment that displays a texture region.</summary>
|
||||
public class MeshAttachment : Attachment {
|
||||
internal float[] vertices, uvs, regionUVs;
|
||||
internal int[] triangles;
|
||||
internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
|
||||
public int HullLength { get; set; }
|
||||
public float[] Vertices { get { return vertices; } set { vertices = value; } }
|
||||
public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } }
|
||||
public float[] UVs { get { return uvs; } set { uvs = value; } }
|
||||
public int[] Triangles { get { return triangles; } set { triangles = value; } }
|
||||
|
||||
public float R { get { return r; } set { r = value; } }
|
||||
public float G { get { return g; } set { g = value; } }
|
||||
public float B { get { return b; } set { b = value; } }
|
||||
public float A { get { return a; } set { a = value; } }
|
||||
|
||||
public String Path { get; set; }
|
||||
public Object RendererObject { get; set; }
|
||||
public float RegionU { get; set; }
|
||||
public float RegionV { get; set; }
|
||||
public float RegionU2 { get; set; }
|
||||
public float RegionV2 { get; set; }
|
||||
public bool RegionRotate { get; set; }
|
||||
public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
|
||||
public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
|
||||
public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } }
|
||||
public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size.
|
||||
public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } }
|
||||
public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size.
|
||||
|
||||
// Nonessential.
|
||||
public int[] Edges { get; set; }
|
||||
public float Width { get; set; }
|
||||
public float Height { get; set; }
|
||||
|
||||
public MeshAttachment (string name)
|
||||
: base(name) {
|
||||
}
|
||||
|
||||
public void UpdateUVs () {
|
||||
float u = RegionU, v = RegionV, width = RegionU2 - RegionU, height = RegionV2 - RegionV;
|
||||
float[] regionUVs = this.regionUVs;
|
||||
if (this.uvs == null || this.uvs.Length != regionUVs.Length) this.uvs = new float[regionUVs.Length];
|
||||
float[] uvs = this.uvs;
|
||||
if (RegionRotate) {
|
||||
for (int i = 0, n = uvs.Length; i < n; i += 2) {
|
||||
uvs[i] = u + regionUVs[i + 1] * width;
|
||||
uvs[i + 1] = v + height - regionUVs[i] * height;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0, n = uvs.Length; i < n; i += 2) {
|
||||
uvs[i] = u + regionUVs[i] * width;
|
||||
uvs[i + 1] = v + regionUVs[i + 1] * height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ComputeWorldVertices (Slot slot, float[] worldVertices) {
|
||||
Bone bone = slot.bone;
|
||||
float x = bone.skeleton.x + bone.worldX, y = bone.skeleton.y + bone.worldY;
|
||||
float m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11;
|
||||
float[] vertices = this.vertices;
|
||||
int verticesCount = vertices.Length;
|
||||
if (slot.attachmentVerticesCount == verticesCount) vertices = slot.AttachmentVertices;
|
||||
for (int i = 0; i < verticesCount; i += 2) {
|
||||
float vx = vertices[i];
|
||||
float vy = vertices[i + 1];
|
||||
worldVertices[i] = vx * m00 + vy * m01 + x;
|
||||
worldVertices[i + 1] = vx * m10 + vy * m11 + y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
151
SpineRuntimes/SpineRuntime21/Attachments/RegionAttachment.cs
Normal file
151
SpineRuntimes/SpineRuntime21/Attachments/RegionAttachment.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
/// <summary>Attachment that displays a texture region.</summary>
|
||||
public class RegionAttachment : Attachment {
|
||||
public const int X1 = 0;
|
||||
public const int Y1 = 1;
|
||||
public const int X2 = 2;
|
||||
public const int Y2 = 3;
|
||||
public const int X3 = 4;
|
||||
public const int Y3 = 5;
|
||||
public const int X4 = 6;
|
||||
public const int Y4 = 7;
|
||||
|
||||
internal float x, y, rotation, scaleX = 1, scaleY = 1, width, height;
|
||||
internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
|
||||
internal float[] offset = new float[8], uvs = new float[8];
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
public float Rotation { get { return rotation; } set { rotation = value; } }
|
||||
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
public float Width { get { return width; } set { width = value; } }
|
||||
public float Height { get { return height; } set { height = value; } }
|
||||
|
||||
public float R { get { return r; } set { r = value; } }
|
||||
public float G { get { return g; } set { g = value; } }
|
||||
public float B { get { return b; } set { b = value; } }
|
||||
public float A { get { return a; } set { a = value; } }
|
||||
|
||||
public String Path { get; set; }
|
||||
public Object RendererObject { get; set; }
|
||||
public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
|
||||
public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
|
||||
public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } }
|
||||
public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size.
|
||||
public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } }
|
||||
public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size.
|
||||
|
||||
public float[] Offset { get { return offset; } }
|
||||
public float[] UVs { get { return uvs; } }
|
||||
|
||||
public RegionAttachment (string name)
|
||||
: base(name) {
|
||||
}
|
||||
|
||||
public void SetUVs (float u, float v, float u2, float v2, bool rotate) {
|
||||
float[] uvs = this.uvs;
|
||||
if (rotate) {
|
||||
uvs[X2] = u;
|
||||
uvs[Y2] = v2;
|
||||
uvs[X3] = u;
|
||||
uvs[Y3] = v;
|
||||
uvs[X4] = u2;
|
||||
uvs[Y4] = v;
|
||||
uvs[X1] = u2;
|
||||
uvs[Y1] = v2;
|
||||
} else {
|
||||
uvs[X1] = u;
|
||||
uvs[Y1] = v2;
|
||||
uvs[X2] = u;
|
||||
uvs[Y2] = v;
|
||||
uvs[X3] = u2;
|
||||
uvs[Y3] = v;
|
||||
uvs[X4] = u2;
|
||||
uvs[Y4] = v2;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateOffset () {
|
||||
float width = this.width;
|
||||
float height = this.height;
|
||||
float scaleX = this.scaleX;
|
||||
float scaleY = this.scaleY;
|
||||
float regionScaleX = width / regionOriginalWidth * scaleX;
|
||||
float regionScaleY = height / regionOriginalHeight * scaleY;
|
||||
float localX = -width / 2 * scaleX + regionOffsetX * regionScaleX;
|
||||
float localY = -height / 2 * scaleY + regionOffsetY * regionScaleY;
|
||||
float localX2 = localX + regionWidth * regionScaleX;
|
||||
float localY2 = localY + regionHeight * regionScaleY;
|
||||
float radians = rotation * (float)Math.PI / 180;
|
||||
float cos = (float)Math.Cos(radians);
|
||||
float sin = (float)Math.Sin(radians);
|
||||
float x = this.x;
|
||||
float y = this.y;
|
||||
float localXCos = localX * cos + x;
|
||||
float localXSin = localX * sin;
|
||||
float localYCos = localY * cos + y;
|
||||
float localYSin = localY * sin;
|
||||
float localX2Cos = localX2 * cos + x;
|
||||
float localX2Sin = localX2 * sin;
|
||||
float localY2Cos = localY2 * cos + y;
|
||||
float localY2Sin = localY2 * sin;
|
||||
float[] offset = this.offset;
|
||||
offset[X1] = localXCos - localYSin;
|
||||
offset[Y1] = localYCos + localXSin;
|
||||
offset[X2] = localXCos - localY2Sin;
|
||||
offset[Y2] = localY2Cos + localXSin;
|
||||
offset[X3] = localX2Cos - localY2Sin;
|
||||
offset[Y3] = localY2Cos + localX2Sin;
|
||||
offset[X4] = localX2Cos - localYSin;
|
||||
offset[Y4] = localYCos + localX2Sin;
|
||||
}
|
||||
|
||||
public void ComputeWorldVertices (Bone bone, float[] worldVertices) {
|
||||
float x = bone.skeleton.x + bone.worldX, y = bone.skeleton.y + bone.worldY;
|
||||
float m00 = bone.m00, m01 = bone.m01, m10 = bone.m10, m11 = bone.m11;
|
||||
float[] offset = this.offset;
|
||||
worldVertices[X1] = offset[X1] * m00 + offset[Y1] * m01 + x;
|
||||
worldVertices[Y1] = offset[X1] * m10 + offset[Y1] * m11 + y;
|
||||
worldVertices[X2] = offset[X2] * m00 + offset[Y2] * m01 + x;
|
||||
worldVertices[Y2] = offset[X2] * m10 + offset[Y2] * m11 + y;
|
||||
worldVertices[X3] = offset[X3] * m00 + offset[Y3] * m01 + x;
|
||||
worldVertices[Y3] = offset[X3] * m10 + offset[Y3] * m11 + y;
|
||||
worldVertices[X4] = offset[X4] * m00 + offset[Y4] * m01 + x;
|
||||
worldVertices[Y4] = offset[X4] * m10 + offset[Y4] * m11 + y;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
/// <summary>Attachment that displays a texture region.</summary>
|
||||
public class SkinnedMeshAttachment : Attachment {
|
||||
internal int[] bones;
|
||||
internal float[] weights, uvs, regionUVs;
|
||||
internal int[] triangles;
|
||||
internal float regionOffsetX, regionOffsetY, regionWidth, regionHeight, regionOriginalWidth, regionOriginalHeight;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
|
||||
public int HullLength { get; set; }
|
||||
public int[] Bones { get { return bones; } set { bones = value; } }
|
||||
public float[] Weights { get { return weights; } set { weights = value; } }
|
||||
public float[] RegionUVs { get { return regionUVs; } set { regionUVs = value; } }
|
||||
public float[] UVs { get { return uvs; } set { uvs = value; } }
|
||||
public int[] Triangles { get { return triangles; } set { triangles = value; } }
|
||||
|
||||
public float R { get { return r; } set { r = value; } }
|
||||
public float G { get { return g; } set { g = value; } }
|
||||
public float B { get { return b; } set { b = value; } }
|
||||
public float A { get { return a; } set { a = value; } }
|
||||
|
||||
public String Path { get; set; }
|
||||
public Object RendererObject { get; set; }
|
||||
public float RegionU { get; set; }
|
||||
public float RegionV { get; set; }
|
||||
public float RegionU2 { get; set; }
|
||||
public float RegionV2 { get; set; }
|
||||
public bool RegionRotate { get; set; }
|
||||
public float RegionOffsetX { get { return regionOffsetX; } set { regionOffsetX = value; } }
|
||||
public float RegionOffsetY { get { return regionOffsetY; } set { regionOffsetY = value; } } // Pixels stripped from the bottom left, unrotated.
|
||||
public float RegionWidth { get { return regionWidth; } set { regionWidth = value; } }
|
||||
public float RegionHeight { get { return regionHeight; } set { regionHeight = value; } } // Unrotated, stripped size.
|
||||
public float RegionOriginalWidth { get { return regionOriginalWidth; } set { regionOriginalWidth = value; } }
|
||||
public float RegionOriginalHeight { get { return regionOriginalHeight; } set { regionOriginalHeight = value; } } // Unrotated, unstripped size.
|
||||
|
||||
// Nonessential.
|
||||
public int[] Edges { get; set; }
|
||||
public float Width { get; set; }
|
||||
public float Height { get; set; }
|
||||
|
||||
public SkinnedMeshAttachment (string name)
|
||||
: base(name) {
|
||||
}
|
||||
|
||||
public void UpdateUVs () {
|
||||
float u = RegionU, v = RegionV, width = RegionU2 - RegionU, height = RegionV2 - RegionV;
|
||||
float[] regionUVs = this.regionUVs;
|
||||
if (this.uvs == null || this.uvs.Length != regionUVs.Length) this.uvs = new float[regionUVs.Length];
|
||||
float[] uvs = this.uvs;
|
||||
if (RegionRotate) {
|
||||
for (int i = 0, n = uvs.Length; i < n; i += 2) {
|
||||
uvs[i] = u + regionUVs[i + 1] * width;
|
||||
uvs[i + 1] = v + height - regionUVs[i] * height;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0, n = uvs.Length; i < n; i += 2) {
|
||||
uvs[i] = u + regionUVs[i] * width;
|
||||
uvs[i + 1] = v + regionUVs[i + 1] * height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ComputeWorldVertices (Slot slot, float[] worldVertices) {
|
||||
Skeleton skeleton = slot.bone.skeleton;
|
||||
List<Bone> skeletonBones = skeleton.bones;
|
||||
float x = skeleton.x, y = skeleton.y;
|
||||
float[] weights = this.weights;
|
||||
int[] bones = this.bones;
|
||||
if (slot.attachmentVerticesCount == 0) {
|
||||
for (int w = 0, v = 0, b = 0, n = bones.Length; v < n; w += 2) {
|
||||
float wx = 0, wy = 0;
|
||||
int nn = bones[v++] + v;
|
||||
for (; v < nn; v++, b += 3) {
|
||||
Bone bone = skeletonBones[bones[v]];
|
||||
float vx = weights[b], vy = weights[b + 1], weight = weights[b + 2];
|
||||
wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight;
|
||||
wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight;
|
||||
}
|
||||
worldVertices[w] = wx + x;
|
||||
worldVertices[w + 1] = wy + y;
|
||||
}
|
||||
} else {
|
||||
float[] ffd = slot.AttachmentVertices;
|
||||
for (int w = 0, v = 0, b = 0, f = 0, n = bones.Length; v < n; w += 2) {
|
||||
float wx = 0, wy = 0;
|
||||
int nn = bones[v++] + v;
|
||||
for (; v < nn; v++, b += 3, f += 2) {
|
||||
Bone bone = skeletonBones[bones[v]];
|
||||
float vx = weights[b] + ffd[f], vy = weights[b + 1] + ffd[f + 1], weight = weights[b + 2];
|
||||
wx += (vx * bone.m00 + vy * bone.m01 + bone.worldX) * weight;
|
||||
wy += (vx * bone.m10 + vy * bone.m11 + bone.worldY) * weight;
|
||||
}
|
||||
worldVertices[w] = wx + x;
|
||||
worldVertices[w + 1] = wy + y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
154
SpineRuntimes/SpineRuntime21/Bone.cs
Normal file
154
SpineRuntimes/SpineRuntime21/Bone.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class Bone{
|
||||
static readonly public bool yDown = false;
|
||||
|
||||
internal BoneData data;
|
||||
internal Skeleton skeleton;
|
||||
internal Bone parent;
|
||||
internal List<Bone> children = new List<Bone>();
|
||||
internal float x, y, rotation, rotationIK, scaleX, scaleY;
|
||||
internal bool flipX, flipY;
|
||||
internal float m00, m01, m10, m11;
|
||||
internal float worldX, worldY, worldRotation, worldScaleX, worldScaleY;
|
||||
internal bool worldFlipX, worldFlipY;
|
||||
|
||||
public BoneData Data { get { return data; } }
|
||||
public Skeleton Skeleton { get { return skeleton; } }
|
||||
public Bone Parent { get { return parent; } }
|
||||
public List<Bone> Children { get { return children; } }
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
/// <summary>The forward kinetics rotation.</summary>
|
||||
public float Rotation { get { return rotation; } set { rotation = value; } }
|
||||
/// <summary>The inverse kinetics rotation, as calculated by any IK constraints.</summary>
|
||||
public float RotationIK { get { return rotationIK; } set { rotationIK = value; } }
|
||||
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
public bool FlipX { get { return flipX; } set { flipX = value; } }
|
||||
public bool FlipY { get { return flipY; } set { flipY = value; } }
|
||||
|
||||
public float M00 { get { return m00; } }
|
||||
public float M01 { get { return m01; } }
|
||||
public float M10 { get { return m10; } }
|
||||
public float M11 { get { return m11; } }
|
||||
public float WorldX { get { return worldX; } }
|
||||
public float WorldY { get { return worldY; } }
|
||||
public float WorldRotation { get { return worldRotation; } }
|
||||
public float WorldScaleX { get { return worldScaleX; } }
|
||||
public float WorldScaleY { get { return worldScaleY; } }
|
||||
public bool WorldFlipX { get { return worldFlipX; } set { worldFlipX = value; } }
|
||||
public bool WorldFlipY { get { return worldFlipY; } set { worldFlipY = value; } }
|
||||
|
||||
/// <param name="parent">May be null.</param>
|
||||
public Bone (BoneData data, Skeleton skeleton, Bone parent) {
|
||||
if (data == null) throw new ArgumentNullException("data cannot be null.");
|
||||
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
|
||||
this.data = data;
|
||||
this.skeleton = skeleton;
|
||||
this.parent = parent;
|
||||
SetToSetupPose();
|
||||
}
|
||||
|
||||
/// <summary>Computes the world SRT using the parent bone and the local SRT.</summary>
|
||||
public void UpdateWorldTransform () {
|
||||
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;
|
||||
worldY = x * parent.m10 + y * parent.m11 + parent.worldY;
|
||||
if (data.inheritScale) {
|
||||
worldScaleX = parent.worldScaleX * scaleX;
|
||||
worldScaleY = parent.worldScaleY * scaleY;
|
||||
} else {
|
||||
worldScaleX = scaleX;
|
||||
worldScaleY = scaleY;
|
||||
}
|
||||
worldRotation = data.inheritRotation ? parent.worldRotation + rotationIK : rotationIK;
|
||||
worldFlipX = parent.worldFlipX != flipX;
|
||||
worldFlipY = parent.worldFlipY != flipY;
|
||||
} else {
|
||||
worldX = x * sx;
|
||||
worldY = y * sy;
|
||||
worldScaleX = scaleX;
|
||||
worldScaleY = scaleY;
|
||||
worldRotation = rotationIK;
|
||||
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);
|
||||
m00 = cos * worldScaleX * sx;
|
||||
m01 = -sin * worldScaleY * sx;
|
||||
m10 = sin * worldScaleX * sy;
|
||||
m11 = cos * worldScaleY * sy;
|
||||
}
|
||||
|
||||
public void SetToSetupPose () {
|
||||
BoneData data = this.data;
|
||||
x = data.x;
|
||||
y = data.y;
|
||||
rotation = data.rotation;
|
||||
rotationIK = rotation;
|
||||
scaleX = data.scaleX;
|
||||
scaleY = data.scaleY;
|
||||
flipX = data.flipX;
|
||||
flipY = data.flipY;
|
||||
}
|
||||
|
||||
public void worldToLocal (float worldX, float worldY, out float localX, out float localY) {
|
||||
float dx = worldX - this.worldX, dy = worldY - this.worldY;
|
||||
float m00 = this.m00, m10 = this.m10, m01 = this.m01, m11 = this.m11;
|
||||
if (worldFlipX != (worldFlipY != yDown)) {
|
||||
m00 = -m00;
|
||||
m11 = -m11;
|
||||
}
|
||||
float invDet = 1 / (m00 * m11 - m01 * m10);
|
||||
localX = (dx * m00 * invDet - dy * m01 * invDet);
|
||||
localY = (dy * m11 * invDet - dx * m10 * invDet);
|
||||
}
|
||||
|
||||
public void localToWorld (float localX, float localY, out float worldX, out float worldY) {
|
||||
worldX = localX * m00 + localY * m01 + this.worldX;
|
||||
worldY = localX * m10 + localY * m11 + this.worldY;
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return data.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
SpineRuntimes/SpineRuntime21/BoneData.cs
Normal file
66
SpineRuntimes/SpineRuntime21/BoneData.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class BoneData {
|
||||
internal BoneData parent;
|
||||
internal String name;
|
||||
internal float length, x, y, rotation, scaleX = 1, scaleY = 1;
|
||||
internal bool flipX, flipY;
|
||||
internal bool inheritScale = true, inheritRotation = true;
|
||||
|
||||
/// <summary>May be null.</summary>
|
||||
public BoneData Parent { get { return parent; } }
|
||||
public String Name { get { return name; } }
|
||||
public float Length { get { return length; } set { length = value; } }
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
public float Rotation { get { return rotation; } set { rotation = value; } }
|
||||
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
public bool FlipX { get { return flipX; } set { flipX = value; } }
|
||||
public bool FlipY { get { return flipY; } set { flipY = value; } }
|
||||
public bool InheritScale { get { return inheritScale; } set { inheritScale = value; } }
|
||||
public bool InheritRotation { get { return inheritRotation; } set { inheritRotation = value; } }
|
||||
|
||||
/// <param name="parent">May be null.</param>
|
||||
public BoneData (String name, BoneData parent) {
|
||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||
this.name = name;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
48
SpineRuntimes/SpineRuntime21/Event.cs
Normal file
48
SpineRuntimes/SpineRuntime21/Event.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class Event {
|
||||
public EventData Data { get; private set; }
|
||||
public int Int { get; set; }
|
||||
public float Float { get; set; }
|
||||
public String String { get; set; }
|
||||
|
||||
public Event (EventData data) {
|
||||
Data = data;
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return Data.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
SpineRuntimes/SpineRuntime21/EventData.cs
Normal file
51
SpineRuntimes/SpineRuntime21/EventData.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class EventData {
|
||||
internal String name;
|
||||
|
||||
public String Name { get { return name; } }
|
||||
public int Int { get; set; }
|
||||
public float Float { get; set; }
|
||||
public String String { get; set; }
|
||||
|
||||
public EventData (String name) {
|
||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
150
SpineRuntimes/SpineRuntime21/IkConstraint.cs
Normal file
150
SpineRuntimes/SpineRuntime21/IkConstraint.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class IkConstraint {
|
||||
private const float radDeg = 180 / (float)Math.PI;
|
||||
|
||||
internal IkConstraintData data;
|
||||
internal List<Bone> bones = new List<Bone>();
|
||||
internal Bone target;
|
||||
internal int bendDirection;
|
||||
internal float mix;
|
||||
|
||||
public IkConstraintData Data { get { return data; } }
|
||||
public List<Bone> Bones { get { return bones; } }
|
||||
public Bone Target { get { return target; } set { target = value; } }
|
||||
public int BendDirection { get { return bendDirection; } set { bendDirection = value; } }
|
||||
public float Mix { get { return mix; } set { mix = value; } }
|
||||
|
||||
public IkConstraint (IkConstraintData data, Skeleton skeleton) {
|
||||
if (data == null) throw new ArgumentNullException("data cannot be null.");
|
||||
if (skeleton == null) throw new ArgumentNullException("skeleton cannot be null.");
|
||||
this.data = data;
|
||||
mix = data.mix;
|
||||
bendDirection = data.bendDirection;
|
||||
|
||||
bones = new List<Bone>(data.bones.Count);
|
||||
foreach (BoneData boneData in data.bones)
|
||||
bones.Add(skeleton.FindBone(boneData.name));
|
||||
target = skeleton.FindBone(data.target.name);
|
||||
}
|
||||
|
||||
public void apply () {
|
||||
Bone target = this.target;
|
||||
List<Bone> bones = this.bones;
|
||||
switch (bones.Count) {
|
||||
case 1:
|
||||
apply(bones[0], target.worldX, target.worldY, mix);
|
||||
break;
|
||||
case 2:
|
||||
apply(bones[0], bones[1], target.worldX, target.worldY, bendDirection, mix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return data.name;
|
||||
}
|
||||
|
||||
/// <summary>Adjusts the bone rotation so the tip is as close to the target position as possible. The target is specified
|
||||
/// in the world coordinate system.</summary>
|
||||
static public void apply (Bone bone, float targetX, float targetY, float alpha) {
|
||||
float parentRotation = (!bone.data.inheritRotation || bone.parent == null) ? 0 : bone.parent.worldRotation;
|
||||
float rotation = bone.rotation;
|
||||
float rotationIK = (float)Math.Atan2(targetY - bone.worldY, targetX - bone.worldX) * radDeg;
|
||||
if (bone.worldFlipX != (bone.worldFlipY != Bone.yDown)) rotationIK = -rotationIK;
|
||||
rotationIK -= parentRotation;
|
||||
bone.rotationIK = rotation + (rotationIK - rotation) * alpha;
|
||||
}
|
||||
|
||||
/// <summary>Adjusts the parent and child bone rotations so the tip of the child is as close to the target position as
|
||||
/// possible. The target is specified in the world coordinate system.</summary>
|
||||
/// <param name="child">Any descendant bone of the parent.</param>
|
||||
static public void apply (Bone parent, Bone child, float targetX, float targetY, int bendDirection, float alpha) {
|
||||
float childRotation = child.rotation, parentRotation = parent.rotation;
|
||||
if (alpha == 0) {
|
||||
child.rotationIK = childRotation;
|
||||
parent.rotationIK = parentRotation;
|
||||
return;
|
||||
}
|
||||
float positionX, positionY;
|
||||
Bone parentParent = parent.parent;
|
||||
if (parentParent != null) {
|
||||
parentParent.worldToLocal(targetX, targetY, out positionX, out positionY);
|
||||
targetX = (positionX - parent.x) * parentParent.worldScaleX;
|
||||
targetY = (positionY - parent.y) * parentParent.worldScaleY;
|
||||
} else {
|
||||
targetX -= parent.x;
|
||||
targetY -= parent.y;
|
||||
}
|
||||
if (child.parent == parent) {
|
||||
positionX = child.x;
|
||||
positionY = child.y;
|
||||
} else {
|
||||
child.parent.localToWorld(child.x, child.y, out positionX, out positionY);
|
||||
parent.worldToLocal(positionX, positionY, out positionX, out positionY);
|
||||
}
|
||||
float childX = positionX * parent.worldScaleX, childY = positionY * parent.worldScaleY;
|
||||
float offset = (float)Math.Atan2(childY, childX);
|
||||
float len1 = (float)Math.Sqrt(childX * childX + childY * childY), len2 = child.data.length * child.worldScaleX;
|
||||
// Based on code by Ryan Juckett with permission: Copyright (c) 2008-2009 Ryan Juckett, http://www.ryanjuckett.com/
|
||||
float cosDenom = 2 * len1 * len2;
|
||||
if (cosDenom < 0.0001f) {
|
||||
child.rotationIK = childRotation + ((float)Math.Atan2(targetY, targetX) * radDeg - parentRotation - childRotation)
|
||||
* alpha;
|
||||
return;
|
||||
}
|
||||
float cos = (targetX * targetX + targetY * targetY - len1 * len1 - len2 * len2) / cosDenom;
|
||||
if (cos < -1)
|
||||
cos = -1;
|
||||
else if (cos > 1)
|
||||
cos = 1;
|
||||
float childAngle = (float)Math.Acos(cos) * bendDirection;
|
||||
float adjacent = len1 + len2 * cos, opposite = len2 * (float)Math.Sin(childAngle);
|
||||
float parentAngle = (float)Math.Atan2(targetY * adjacent - targetX * opposite, targetX * adjacent + targetY * opposite);
|
||||
float rotation = (parentAngle - offset) * radDeg - parentRotation;
|
||||
if (rotation > 180)
|
||||
rotation -= 360;
|
||||
else if (rotation < -180) //
|
||||
rotation += 360;
|
||||
parent.rotationIK = parentRotation + rotation * alpha;
|
||||
rotation = (childAngle + offset) * radDeg - childRotation;
|
||||
if (rotation > 180)
|
||||
rotation -= 360;
|
||||
else if (rotation < -180) //
|
||||
rotation += 360;
|
||||
child.rotationIK = childRotation + (rotation + parent.worldRotation - child.parent.worldRotation) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
57
SpineRuntimes/SpineRuntime21/IkConstraintData.cs
Normal file
57
SpineRuntimes/SpineRuntime21/IkConstraintData.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class IkConstraintData {
|
||||
internal String name;
|
||||
internal List<BoneData> bones = new List<BoneData>();
|
||||
internal BoneData target;
|
||||
internal int bendDirection = 1;
|
||||
internal float mix = 1;
|
||||
|
||||
public String Name { get { return name; } }
|
||||
public List<BoneData> Bones { get { return bones; } }
|
||||
public BoneData Target { get { return target; } set { target = value; } }
|
||||
public int BendDirection { get { return bendDirection; } set { bendDirection = value; } }
|
||||
public float Mix { get { return mix; } set { mix = value; } }
|
||||
|
||||
public IkConstraintData (String name) {
|
||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
542
SpineRuntimes/SpineRuntime21/Json.cs
Normal file
542
SpineRuntimes/SpineRuntime21/Json.cs
Normal file
@@ -0,0 +1,542 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Calvin Rien
|
||||
*
|
||||
* Based on the JSON parser by Patrick van Bergen
|
||||
* http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
|
||||
*
|
||||
* Simplified it so that it doesn't throw exceptions
|
||||
* and can be used in Unity iPhone with maximum code stripping.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
|
||||
namespace SpineRuntime21
|
||||
{
|
||||
// Example usage:
|
||||
//
|
||||
// using UnityEngine;
|
||||
// using System.Collections;
|
||||
// using System.Collections.Generic;
|
||||
// using MiniJSON;
|
||||
//
|
||||
// public class MiniJSONTest : MonoBehaviour {
|
||||
// void Start () {
|
||||
// var jsonString = "{ \"array\": [1.44,2,3], " +
|
||||
// "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
|
||||
// "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
|
||||
// "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
|
||||
// "\"int\": 65536, " +
|
||||
// "\"float\": 3.1415926, " +
|
||||
// "\"bool\": true, " +
|
||||
// "\"null\": null }";
|
||||
//
|
||||
// var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;
|
||||
//
|
||||
// Debug.Log("deserialized: " + dict.GetType());
|
||||
// Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]);
|
||||
// Debug.Log("dict['string']: " + (string) dict["string"]);
|
||||
// Debug.Log("dict['float']: " + (float) dict["float"]);
|
||||
// Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs
|
||||
// Debug.Log("dict['unicode']: " + (string) dict["unicode"]);
|
||||
//
|
||||
// var str = Json.Serialize(dict);
|
||||
//
|
||||
// Debug.Log("serialized: " + str);
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// This class encodes and decodes JSON strings.
|
||||
/// Spec. details, see http://www.json.org/
|
||||
///
|
||||
/// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
|
||||
/// All numbers are parsed to floats.
|
||||
/// </summary>
|
||||
public static class Json {
|
||||
/// <summary>
|
||||
/// Parses the string json into a value
|
||||
/// </summary>
|
||||
/// <param name="json">A JSON string.</param>
|
||||
/// <returns>An List<object>, a Dictionary<string, object>, a float, an integer,a string, null, true, or false</returns>
|
||||
public static object Deserialize (TextReader json) {
|
||||
if (json == null) {
|
||||
return null;
|
||||
}
|
||||
return Parser.Parse(json);
|
||||
}
|
||||
|
||||
sealed class Parser : IDisposable {
|
||||
const string WHITE_SPACE = " \t\n\r";
|
||||
const string WORD_BREAK = " \t\n\r{}[],:\"";
|
||||
|
||||
enum TOKEN {
|
||||
NONE,
|
||||
CURLY_OPEN,
|
||||
CURLY_CLOSE,
|
||||
SQUARED_OPEN,
|
||||
SQUARED_CLOSE,
|
||||
COLON,
|
||||
COMMA,
|
||||
STRING,
|
||||
NUMBER,
|
||||
TRUE,
|
||||
FALSE,
|
||||
NULL
|
||||
};
|
||||
|
||||
TextReader json;
|
||||
|
||||
Parser(TextReader reader) {
|
||||
json = reader;
|
||||
}
|
||||
|
||||
public static object Parse (TextReader reader) {
|
||||
using (var instance = new Parser(reader)) {
|
||||
return instance.ParseValue();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
json.Dispose();
|
||||
json = null;
|
||||
}
|
||||
|
||||
Dictionary<string, object> ParseObject() {
|
||||
Dictionary<string, object> table = new Dictionary<string, object>();
|
||||
|
||||
// ditch opening brace
|
||||
json.Read();
|
||||
|
||||
// {
|
||||
while (true) {
|
||||
switch (NextToken) {
|
||||
case TOKEN.NONE:
|
||||
return null;
|
||||
case TOKEN.COMMA:
|
||||
continue;
|
||||
case TOKEN.CURLY_CLOSE:
|
||||
return table;
|
||||
default:
|
||||
// name
|
||||
string name = ParseString();
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// :
|
||||
if (NextToken != TOKEN.COLON) {
|
||||
return null;
|
||||
}
|
||||
// ditch the colon
|
||||
json.Read();
|
||||
|
||||
// value
|
||||
table[name] = ParseValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<object> ParseArray() {
|
||||
List<object> array = new List<object>();
|
||||
|
||||
// ditch opening bracket
|
||||
json.Read();
|
||||
|
||||
// [
|
||||
var parsing = true;
|
||||
while (parsing) {
|
||||
TOKEN nextToken = NextToken;
|
||||
|
||||
switch (nextToken) {
|
||||
case TOKEN.NONE:
|
||||
return null;
|
||||
case TOKEN.COMMA:
|
||||
continue;
|
||||
case TOKEN.SQUARED_CLOSE:
|
||||
parsing = false;
|
||||
break;
|
||||
default:
|
||||
object value = ParseByToken(nextToken);
|
||||
|
||||
array.Add(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
object ParseValue() {
|
||||
TOKEN nextToken = NextToken;
|
||||
return ParseByToken(nextToken);
|
||||
}
|
||||
|
||||
object ParseByToken(TOKEN token) {
|
||||
switch (token) {
|
||||
case TOKEN.STRING:
|
||||
return ParseString();
|
||||
case TOKEN.NUMBER:
|
||||
return ParseNumber();
|
||||
case TOKEN.CURLY_OPEN:
|
||||
return ParseObject();
|
||||
case TOKEN.SQUARED_OPEN:
|
||||
return ParseArray();
|
||||
case TOKEN.TRUE:
|
||||
return true;
|
||||
case TOKEN.FALSE:
|
||||
return false;
|
||||
case TOKEN.NULL:
|
||||
return null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
string ParseString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
char c;
|
||||
|
||||
// ditch opening quote
|
||||
json.Read();
|
||||
|
||||
bool parsing = true;
|
||||
while (parsing) {
|
||||
|
||||
if (json.Peek() == -1) {
|
||||
parsing = false;
|
||||
break;
|
||||
}
|
||||
|
||||
c = NextChar;
|
||||
switch (c) {
|
||||
case '"':
|
||||
parsing = false;
|
||||
break;
|
||||
case '\\':
|
||||
if (json.Peek() == -1) {
|
||||
parsing = false;
|
||||
break;
|
||||
}
|
||||
|
||||
c = NextChar;
|
||||
switch (c) {
|
||||
case '"':
|
||||
case '\\':
|
||||
case '/':
|
||||
s.Append(c);
|
||||
break;
|
||||
case 'b':
|
||||
s.Append('\b');
|
||||
break;
|
||||
case 'f':
|
||||
s.Append('\f');
|
||||
break;
|
||||
case 'n':
|
||||
s.Append('\n');
|
||||
break;
|
||||
case 'r':
|
||||
s.Append('\r');
|
||||
break;
|
||||
case 't':
|
||||
s.Append('\t');
|
||||
break;
|
||||
case 'u':
|
||||
var hex = new StringBuilder();
|
||||
|
||||
for (int i=0; i< 4; i++) {
|
||||
hex.Append(NextChar);
|
||||
}
|
||||
|
||||
s.Append((char) Convert.ToInt32(hex.ToString(), 16));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
s.Append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return s.ToString();
|
||||
}
|
||||
|
||||
object ParseNumber() {
|
||||
string number = NextWord;
|
||||
float parsedFloat;
|
||||
float.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out parsedFloat);
|
||||
return parsedFloat;
|
||||
}
|
||||
|
||||
void EatWhitespace() {
|
||||
while (WHITE_SPACE.IndexOf(PeekChar) != -1) {
|
||||
json.Read();
|
||||
|
||||
if (json.Peek() == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char PeekChar {
|
||||
get {
|
||||
return Convert.ToChar(json.Peek());
|
||||
}
|
||||
}
|
||||
|
||||
char NextChar {
|
||||
get {
|
||||
return Convert.ToChar(json.Read());
|
||||
}
|
||||
}
|
||||
|
||||
string NextWord {
|
||||
get {
|
||||
StringBuilder word = new StringBuilder();
|
||||
|
||||
while (WORD_BREAK.IndexOf(PeekChar) == -1) {
|
||||
word.Append(NextChar);
|
||||
|
||||
if (json.Peek() == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return word.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
TOKEN NextToken {
|
||||
get {
|
||||
EatWhitespace();
|
||||
|
||||
if (json.Peek() == -1) {
|
||||
return TOKEN.NONE;
|
||||
}
|
||||
|
||||
char c = PeekChar;
|
||||
switch (c) {
|
||||
case '{':
|
||||
return TOKEN.CURLY_OPEN;
|
||||
case '}':
|
||||
json.Read();
|
||||
return TOKEN.CURLY_CLOSE;
|
||||
case '[':
|
||||
return TOKEN.SQUARED_OPEN;
|
||||
case ']':
|
||||
json.Read();
|
||||
return TOKEN.SQUARED_CLOSE;
|
||||
case ',':
|
||||
json.Read();
|
||||
return TOKEN.COMMA;
|
||||
case '"':
|
||||
return TOKEN.STRING;
|
||||
case ':':
|
||||
return TOKEN.COLON;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
return TOKEN.NUMBER;
|
||||
}
|
||||
|
||||
string word = NextWord;
|
||||
|
||||
switch (word) {
|
||||
case "false":
|
||||
return TOKEN.FALSE;
|
||||
case "true":
|
||||
return TOKEN.TRUE;
|
||||
case "null":
|
||||
return TOKEN.NULL;
|
||||
}
|
||||
|
||||
return TOKEN.NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string
|
||||
/// </summary>
|
||||
/// <param name="json">A Dictionary<string, object> / List<object></param>
|
||||
/// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
|
||||
public static string Serialize(object obj) {
|
||||
return Serializer.Serialize(obj);
|
||||
}
|
||||
|
||||
sealed class Serializer {
|
||||
StringBuilder builder;
|
||||
|
||||
Serializer() {
|
||||
builder = new StringBuilder();
|
||||
}
|
||||
|
||||
public static string Serialize(object obj) {
|
||||
var instance = new Serializer();
|
||||
|
||||
instance.SerializeValue(obj);
|
||||
|
||||
return instance.builder.ToString();
|
||||
}
|
||||
|
||||
void SerializeValue(object value) {
|
||||
IList asList;
|
||||
IDictionary asDict;
|
||||
string asStr;
|
||||
|
||||
if (value == null) {
|
||||
builder.Append("null");
|
||||
}
|
||||
else if ((asStr = value as string) != null) {
|
||||
SerializeString(asStr);
|
||||
}
|
||||
else if (value is bool) {
|
||||
builder.Append(value.ToString().ToLower());
|
||||
}
|
||||
else if ((asList = value as IList) != null) {
|
||||
SerializeArray(asList);
|
||||
}
|
||||
else if ((asDict = value as IDictionary) != null) {
|
||||
SerializeObject(asDict);
|
||||
}
|
||||
else if (value is char) {
|
||||
SerializeString(value.ToString());
|
||||
}
|
||||
else {
|
||||
SerializeOther(value);
|
||||
}
|
||||
}
|
||||
|
||||
void SerializeObject(IDictionary obj) {
|
||||
bool first = true;
|
||||
|
||||
builder.Append('{');
|
||||
|
||||
foreach (object e in obj.Keys) {
|
||||
if (!first) {
|
||||
builder.Append(',');
|
||||
}
|
||||
|
||||
SerializeString(e.ToString());
|
||||
builder.Append(':');
|
||||
|
||||
SerializeValue(obj[e]);
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
builder.Append('}');
|
||||
}
|
||||
|
||||
void SerializeArray(IList anArray) {
|
||||
builder.Append('[');
|
||||
|
||||
bool first = true;
|
||||
|
||||
foreach (object obj in anArray) {
|
||||
if (!first) {
|
||||
builder.Append(',');
|
||||
}
|
||||
|
||||
SerializeValue(obj);
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
builder.Append(']');
|
||||
}
|
||||
|
||||
void SerializeString(string str) {
|
||||
builder.Append('\"');
|
||||
|
||||
char[] charArray = str.ToCharArray();
|
||||
foreach (var c in charArray) {
|
||||
switch (c) {
|
||||
case '"':
|
||||
builder.Append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
builder.Append("\\\\");
|
||||
break;
|
||||
case '\b':
|
||||
builder.Append("\\b");
|
||||
break;
|
||||
case '\f':
|
||||
builder.Append("\\f");
|
||||
break;
|
||||
case '\n':
|
||||
builder.Append("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
builder.Append("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
builder.Append("\\t");
|
||||
break;
|
||||
default:
|
||||
int codepoint = Convert.ToInt32(c);
|
||||
if ((codepoint >= 32) && (codepoint <= 126)) {
|
||||
builder.Append(c);
|
||||
}
|
||||
else {
|
||||
builder.Append("\\u" + Convert.ToString(codepoint, 16).PadLeft(4, '0'));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append('\"');
|
||||
}
|
||||
|
||||
void SerializeOther(object value) {
|
||||
if (value is float
|
||||
|| value is int
|
||||
|| value is uint
|
||||
|| value is long
|
||||
|| value is float
|
||||
|| value is sbyte
|
||||
|| value is byte
|
||||
|| value is short
|
||||
|| value is ushort
|
||||
|| value is ulong
|
||||
|| value is decimal) {
|
||||
builder.Append(value.ToString());
|
||||
}
|
||||
else {
|
||||
SerializeString(value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
357
SpineRuntimes/SpineRuntime21/Skeleton.cs
Normal file
357
SpineRuntimes/SpineRuntime21/Skeleton.cs
Normal file
@@ -0,0 +1,357 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class Skeleton {
|
||||
internal SkeletonData data;
|
||||
internal List<Bone> bones;
|
||||
internal List<Slot> slots;
|
||||
internal List<Slot> drawOrder;
|
||||
internal List<IkConstraint> ikConstraints;
|
||||
private List<List<Bone>> boneCache = new List<List<Bone>>();
|
||||
internal Skin skin;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
internal float time;
|
||||
internal float scaleX = 1, scaleY = 1;
|
||||
internal float x, y;
|
||||
|
||||
public SkeletonData Data { get { return data; } }
|
||||
public List<Bone> Bones { get { return bones; } }
|
||||
public List<Slot> Slots { get { return slots; } }
|
||||
public List<Slot> DrawOrder { get { return drawOrder; } }
|
||||
public List<IkConstraint> IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } }
|
||||
public Skin Skin { get { return skin; } set { skin = value; } }
|
||||
public float R { get { return r; } set { r = value; } }
|
||||
public float G { get { return g; } set { g = value; } }
|
||||
public float B { get { return b; } set { b = value; } }
|
||||
public float A { get { return a; } set { a = value; } }
|
||||
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 float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
|
||||
[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];
|
||||
}
|
||||
}
|
||||
|
||||
public Skeleton (SkeletonData data) {
|
||||
if (data == null) throw new ArgumentNullException("data cannot be null.");
|
||||
this.data = data;
|
||||
|
||||
bones = new List<Bone>(data.bones.Count);
|
||||
foreach (BoneData boneData in data.bones) {
|
||||
Bone parent = boneData.parent == null ? null : bones[data.bones.IndexOf(boneData.parent)];
|
||||
Bone bone = new Bone(boneData, this, parent);
|
||||
if (parent != null) parent.children.Add(bone);
|
||||
bones.Add(bone);
|
||||
}
|
||||
|
||||
slots = new List<Slot>(data.slots.Count);
|
||||
drawOrder = new List<Slot>(data.slots.Count);
|
||||
foreach (SlotData slotData in data.slots) {
|
||||
Bone bone = bones[data.bones.IndexOf(slotData.boneData)];
|
||||
Slot slot = new Slot(slotData, bone);
|
||||
slots.Add(slot);
|
||||
drawOrder.Add(slot);
|
||||
}
|
||||
|
||||
ikConstraints = new List<IkConstraint>(data.ikConstraints.Count);
|
||||
foreach (IkConstraintData ikConstraintData in data.ikConstraints)
|
||||
ikConstraints.Add(new IkConstraint(ikConstraintData, this));
|
||||
|
||||
UpdateCache();
|
||||
}
|
||||
|
||||
/// <summary>Caches information about bones and IK constraints. Must be called if bones or IK constraints are added or
|
||||
/// removed.</summary>
|
||||
public void UpdateCache () {
|
||||
List<List<Bone>> boneCache = this.boneCache;
|
||||
List<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
int ikConstraintsCount = ikConstraints.Count;
|
||||
|
||||
int arrayCount = ikConstraintsCount + 1;
|
||||
if (boneCache.Count > arrayCount) boneCache.RemoveRange(arrayCount, boneCache.Count - arrayCount);
|
||||
for (int i = 0, n = boneCache.Count; i < n; i++)
|
||||
boneCache[i].Clear();
|
||||
while (boneCache.Count < arrayCount)
|
||||
boneCache.Add(new List<Bone>());
|
||||
|
||||
List<Bone> nonIkBones = boneCache[0];
|
||||
|
||||
for (int i = 0, n = bones.Count; i < n; i++) {
|
||||
Bone bone = bones[i];
|
||||
Bone current = bone;
|
||||
do {
|
||||
for (int ii = 0; ii < ikConstraintsCount; ii++) {
|
||||
IkConstraint ikConstraint = ikConstraints[ii];
|
||||
Bone parent = ikConstraint.bones[0];
|
||||
Bone child = ikConstraint.bones[ikConstraint.bones.Count - 1];
|
||||
while (true) {
|
||||
if (current == child) {
|
||||
boneCache[ii].Add(bone);
|
||||
boneCache[ii + 1].Add(bone);
|
||||
goto outer;
|
||||
}
|
||||
if (child == parent) break;
|
||||
child = child.parent;
|
||||
}
|
||||
}
|
||||
current = current.parent;
|
||||
} while (current != null);
|
||||
nonIkBones.Add(bone);
|
||||
outer: {}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Updates the world transform for each bone and applies IK constraints.</summary>
|
||||
public void UpdateWorldTransform () {
|
||||
List<Bone> bones = this.bones;
|
||||
for (int ii = 0, nn = bones.Count; ii < nn; ii++) {
|
||||
Bone bone = bones[ii];
|
||||
bone.rotationIK = bone.rotation;
|
||||
}
|
||||
List<List<Bone>> boneCache = this.boneCache;
|
||||
List<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
int i = 0, last = boneCache.Count - 1;
|
||||
while (true) {
|
||||
List<Bone> updateBones = boneCache[i];
|
||||
for (int ii = 0, nn = updateBones.Count; ii < nn; ii++)
|
||||
updateBones[ii].UpdateWorldTransform();
|
||||
if (i == last) break;
|
||||
ikConstraints[i].apply();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Sets the bones and slots to their setup pose values.</summary>
|
||||
public void SetToSetupPose () {
|
||||
SetBonesToSetupPose();
|
||||
SetSlotsToSetupPose();
|
||||
}
|
||||
|
||||
public void SetBonesToSetupPose () {
|
||||
List<Bone> bones = this.bones;
|
||||
for (int i = 0, n = bones.Count; i < n; i++)
|
||||
bones[i].SetToSetupPose();
|
||||
|
||||
List<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
for (int i = 0, n = ikConstraints.Count; i < n; i++) {
|
||||
IkConstraint ikConstraint = ikConstraints[i];
|
||||
ikConstraint.bendDirection = ikConstraint.data.bendDirection;
|
||||
ikConstraint.mix = ikConstraint.data.mix;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSlotsToSetupPose () {
|
||||
List<Slot> slots = this.slots;
|
||||
drawOrder.Clear();
|
||||
drawOrder.AddRange(slots);
|
||||
for (int i = 0, n = slots.Count; i < n; i++)
|
||||
slots[i].SetToSetupPose(i);
|
||||
}
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Bone FindBone (String boneName) {
|
||||
if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
|
||||
List<Bone> bones = this.bones;
|
||||
for (int i = 0, n = bones.Count; i < n; i++) {
|
||||
Bone bone = bones[i];
|
||||
if (bone.data.name == boneName) return bone;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <returns>-1 if the bone was not found.</returns>
|
||||
public int FindBoneIndex (String boneName) {
|
||||
if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
|
||||
List<Bone> bones = this.bones;
|
||||
for (int i = 0, n = bones.Count; i < n; i++)
|
||||
if (bones[i].data.name == boneName) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Slot FindSlot (String slotName) {
|
||||
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
|
||||
List<Slot> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++) {
|
||||
Slot slot = slots[i];
|
||||
if (slot.data.name == slotName) return slot;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <returns>-1 if the bone was not found.</returns>
|
||||
public int FindSlotIndex (String slotName) {
|
||||
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
|
||||
List<Slot> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++)
|
||||
if (slots[i].data.name.Equals(slotName)) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>Sets a skin by name (see SetSkin).</summary>
|
||||
public void SetSkin (String skinName) {
|
||||
Skin skin = data.FindSkin(skinName);
|
||||
if (skin == null) throw new ArgumentException("Skin not found: " + skinName);
|
||||
SetSkin(skin);
|
||||
}
|
||||
|
||||
/// <summary>Sets the skin used to look up attachments before looking in the {@link SkeletonData#getDefaultSkin() default
|
||||
/// skin}. Attachmentsfrom the new skin are attached if the corresponding attachment from the old skin was attached. If
|
||||
/// there was no old skin, each slot's setup mode attachment is attached from the new skin.</summary>
|
||||
/// <param name="newSkin">May be null.</param>
|
||||
public void SetSkin (Skin newSkin) {
|
||||
if (newSkin != null) {
|
||||
if (skin != null)
|
||||
newSkin.AttachAll(this, skin);
|
||||
else {
|
||||
List<Slot> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++) {
|
||||
Slot slot = slots[i];
|
||||
String name = slot.data.attachmentName;
|
||||
if (name != null) {
|
||||
Attachment attachment = newSkin.GetAttachment(i, name);
|
||||
if (attachment != null) slot.Attachment = attachment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
skin = newSkin;
|
||||
}
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Attachment GetAttachment (String slotName, String attachmentName) {
|
||||
return GetAttachment(data.FindSlotIndex(slotName), attachmentName);
|
||||
}
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Attachment GetAttachment (int slotIndex, String attachmentName) {
|
||||
if (attachmentName == null) throw new ArgumentNullException("attachmentName cannot be null.");
|
||||
if (skin != null) {
|
||||
Attachment attachment = skin.GetAttachment(slotIndex, attachmentName);
|
||||
if (attachment != null) return attachment;
|
||||
}
|
||||
if (data.defaultSkin != null) return data.defaultSkin.GetAttachment(slotIndex, attachmentName);
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <param name="attachmentName">May be null.</param>
|
||||
public void SetAttachment (String slotName, String attachmentName) {
|
||||
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
|
||||
List<Slot> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++) {
|
||||
Slot slot = slots[i];
|
||||
if (slot.data.name == slotName) {
|
||||
Attachment attachment = null;
|
||||
if (attachmentName != null) {
|
||||
attachment = GetAttachment(i, attachmentName);
|
||||
if (attachment == null) throw new Exception("Attachment not found: " + attachmentName + ", for slot: " + slotName);
|
||||
}
|
||||
slot.Attachment = attachment;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new Exception("Slot not found: " + slotName);
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
public IkConstraint FindIkConstraint (String ikConstraintName) {
|
||||
if (ikConstraintName == null) throw new ArgumentNullException("ikConstraintName cannot be null.");
|
||||
List<IkConstraint> ikConstraints = this.ikConstraints;
|
||||
for (int i = 0, n = ikConstraints.Count; i < n; i++) {
|
||||
IkConstraint ikConstraint = ikConstraints[i];
|
||||
if (ikConstraint.data.name == ikConstraintName) return ikConstraint;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
663
SpineRuntimes/SpineRuntime21/SkeletonBinary.cs
Normal file
663
SpineRuntimes/SpineRuntime21/SkeletonBinary.cs
Normal file
@@ -0,0 +1,663 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if WINDOWS_STOREAPP
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
#endif
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class SkeletonBinary {
|
||||
public const int TIMELINE_SCALE = 0;
|
||||
public const int TIMELINE_ROTATE = 1;
|
||||
public const int TIMELINE_TRANSLATE = 2;
|
||||
public const int TIMELINE_ATTACHMENT = 3;
|
||||
public const int TIMELINE_COLOR = 4;
|
||||
public const int TIMELINE_FLIPX = 5;
|
||||
public const int TIMELINE_FLIPY = 6;
|
||||
|
||||
public const int CURVE_LINEAR = 0;
|
||||
public const int CURVE_STEPPED = 1;
|
||||
public const int CURVE_BEZIER = 2;
|
||||
|
||||
private AttachmentLoader attachmentLoader;
|
||||
public float Scale { get; set; }
|
||||
private char[] chars = new char[32];
|
||||
private byte[] buffer = new byte[4];
|
||||
|
||||
public SkeletonBinary (params Atlas[] atlasArray)
|
||||
: this(new AtlasAttachmentLoader(atlasArray)) {
|
||||
}
|
||||
|
||||
public SkeletonBinary (AttachmentLoader attachmentLoader) {
|
||||
if (attachmentLoader == null) throw new ArgumentNullException("attachmentLoader cannot be null.");
|
||||
this.attachmentLoader = attachmentLoader;
|
||||
Scale = 1;
|
||||
}
|
||||
|
||||
#if WINDOWS_STOREAPP
|
||||
private async Task<SkeletonData> ReadFile(string path) {
|
||||
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
||||
using (var input = new BufferedStream(await folder.GetFileAsync(path).AsTask().ConfigureAwait(false))) {
|
||||
SkeletonData skeletonData = ReadSkeletonData(input);
|
||||
skeletonData.Name = Path.GetFileNameWithoutExtension(path);
|
||||
return skeletonData;
|
||||
}
|
||||
}
|
||||
|
||||
public SkeletonData ReadSkeletonData (String path) {
|
||||
return this.ReadFile(path).Result;
|
||||
}
|
||||
#else
|
||||
public SkeletonData ReadSkeletonData (String path) {
|
||||
#if WINDOWS_PHONE
|
||||
using (var input = new BufferedStream(Microsoft.Xna.Framework.TitleContainer.OpenStream(path)))
|
||||
{
|
||||
#else
|
||||
using (var input = new BufferedStream(new FileStream(path, FileMode.Open))) {
|
||||
#endif
|
||||
SkeletonData skeletonData = ReadSkeletonData(input);
|
||||
skeletonData.name = Path.GetFileNameWithoutExtension(path);
|
||||
return skeletonData;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public SkeletonData ReadSkeletonData (Stream input) {
|
||||
if (input == null) throw new ArgumentNullException("input cannot be null.");
|
||||
float scale = Scale;
|
||||
|
||||
var skeletonData = new SkeletonData();
|
||||
skeletonData.hash = ReadString(input);
|
||||
if (skeletonData.hash.Length == 0) skeletonData.hash = null;
|
||||
skeletonData.version = ReadString(input);
|
||||
if (skeletonData.version.Length == 0) skeletonData.version = null;
|
||||
skeletonData.width = ReadFloat(input);
|
||||
skeletonData.height = ReadFloat(input);
|
||||
|
||||
bool nonessential = ReadBoolean(input);
|
||||
|
||||
if (nonessential) {
|
||||
skeletonData.imagesPath = ReadString(input);
|
||||
if (skeletonData.imagesPath.Length == 0) skeletonData.imagesPath = null;
|
||||
}
|
||||
|
||||
// Bones.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++) {
|
||||
String name = ReadString(input);
|
||||
BoneData parent = null;
|
||||
int parentIndex = ReadInt(input, true) - 1;
|
||||
if (parentIndex != -1) parent = skeletonData.bones[parentIndex];
|
||||
BoneData boneData = new BoneData(name, parent);
|
||||
boneData.x = ReadFloat(input) * scale;
|
||||
boneData.y = ReadFloat(input) * scale;
|
||||
boneData.scaleX = ReadFloat(input);
|
||||
boneData.scaleY = ReadFloat(input);
|
||||
boneData.rotation = ReadFloat(input);
|
||||
boneData.length = ReadFloat(input) * scale;
|
||||
boneData.flipX = ReadBoolean(input);
|
||||
boneData.flipY = ReadBoolean(input);
|
||||
boneData.inheritScale = ReadBoolean(input);
|
||||
boneData.inheritRotation = ReadBoolean(input);
|
||||
if (nonessential) ReadInt(input); // Skip bone color.
|
||||
skeletonData.bones.Add(boneData);
|
||||
}
|
||||
|
||||
// IK constraints.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++) {
|
||||
IkConstraintData ikConstraintData = new IkConstraintData(ReadString(input));
|
||||
for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++)
|
||||
ikConstraintData.bones.Add(skeletonData.bones[ReadInt(input, true)]);
|
||||
ikConstraintData.target = skeletonData.bones[ReadInt(input, true)];
|
||||
ikConstraintData.mix = ReadFloat(input);
|
||||
ikConstraintData.bendDirection = ReadSByte(input);
|
||||
skeletonData.ikConstraints.Add(ikConstraintData);
|
||||
}
|
||||
|
||||
// Slots.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++) {
|
||||
String slotName = ReadString(input);
|
||||
BoneData boneData = skeletonData.bones[ReadInt(input, true)];
|
||||
SlotData slotData = new SlotData(slotName, boneData);
|
||||
int color = ReadInt(input);
|
||||
slotData.r = ((color & 0xff000000) >> 24) / 255f;
|
||||
slotData.g = ((color & 0x00ff0000) >> 16) / 255f;
|
||||
slotData.b = ((color & 0x0000ff00) >> 8) / 255f;
|
||||
slotData.a = ((color & 0x000000ff)) / 255f;
|
||||
slotData.attachmentName = ReadString(input);
|
||||
slotData.additiveBlending = ReadBoolean(input);
|
||||
skeletonData.slots.Add(slotData);
|
||||
}
|
||||
|
||||
// Default skin.
|
||||
Skin defaultSkin = ReadSkin(input, "default", nonessential);
|
||||
if (defaultSkin != null) {
|
||||
skeletonData.defaultSkin = defaultSkin;
|
||||
skeletonData.skins.Add(defaultSkin);
|
||||
}
|
||||
|
||||
// Skins.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++)
|
||||
skeletonData.skins.Add(ReadSkin(input, ReadString(input), nonessential));
|
||||
|
||||
// Events.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++) {
|
||||
EventData eventData = new EventData(ReadString(input));
|
||||
eventData.Int = ReadInt(input, false);
|
||||
eventData.Float = ReadFloat(input);
|
||||
eventData.String = ReadString(input);
|
||||
skeletonData.events.Add(eventData);
|
||||
}
|
||||
|
||||
// Animations.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++)
|
||||
ReadAnimation(ReadString(input), input, skeletonData);
|
||||
|
||||
skeletonData.bones.TrimExcess();
|
||||
skeletonData.slots.TrimExcess();
|
||||
skeletonData.skins.TrimExcess();
|
||||
skeletonData.events.TrimExcess();
|
||||
skeletonData.animations.TrimExcess();
|
||||
skeletonData.ikConstraints.TrimExcess();
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
/** @return May be null. */
|
||||
private Skin ReadSkin (Stream input, String skinName, bool nonessential) {
|
||||
int slotCount = ReadInt(input, true);
|
||||
if (slotCount == 0) return null;
|
||||
Skin skin = new Skin(skinName);
|
||||
for (int i = 0; i < slotCount; i++) {
|
||||
int slotIndex = ReadInt(input, true);
|
||||
for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) {
|
||||
String name = ReadString(input);
|
||||
skin.AddAttachment(slotIndex, name, ReadAttachment(input, skin, name, nonessential));
|
||||
}
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
|
||||
private Attachment ReadAttachment (Stream input, Skin skin, String attachmentName, bool nonessential) {
|
||||
float scale = Scale;
|
||||
|
||||
String name = ReadString(input);
|
||||
if (name == null) name = attachmentName;
|
||||
|
||||
switch ((AttachmentType)input.ReadByte()) {
|
||||
case AttachmentType.region: {
|
||||
String path = ReadString(input);
|
||||
if (path == null) path = name;
|
||||
RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path);
|
||||
if (region == null) return null;
|
||||
region.Path = path;
|
||||
region.x = ReadFloat(input) * scale;
|
||||
region.y = ReadFloat(input) * scale;
|
||||
region.scaleX = ReadFloat(input);
|
||||
region.scaleY = ReadFloat(input);
|
||||
region.rotation = ReadFloat(input);
|
||||
region.width = ReadFloat(input) * scale;
|
||||
region.height = ReadFloat(input) * scale;
|
||||
int color = ReadInt(input);
|
||||
region.r = ((color & 0xff000000) >> 24) / 255f;
|
||||
region.g = ((color & 0x00ff0000) >> 16) / 255f;
|
||||
region.b = ((color & 0x0000ff00) >> 8) / 255f;
|
||||
region.a = ((color & 0x000000ff)) / 255f;
|
||||
region.UpdateOffset();
|
||||
return region;
|
||||
}
|
||||
case AttachmentType.boundingbox: {
|
||||
BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
|
||||
if (box == null) return null;
|
||||
box.vertices = ReadFloatArray(input, scale);
|
||||
return box;
|
||||
}
|
||||
case AttachmentType.mesh: {
|
||||
String path = ReadString(input);
|
||||
if (path == null) path = name;
|
||||
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
|
||||
if (mesh == null) return null;
|
||||
mesh.Path = path;
|
||||
mesh.regionUVs = ReadFloatArray(input, 1);
|
||||
mesh.triangles = ReadShortArray(input);
|
||||
mesh.vertices = ReadFloatArray(input, scale);
|
||||
mesh.UpdateUVs();
|
||||
int color = ReadInt(input);
|
||||
mesh.r = ((color & 0xff000000) >> 24) / 255f;
|
||||
mesh.g = ((color & 0x00ff0000) >> 16) / 255f;
|
||||
mesh.b = ((color & 0x0000ff00) >> 8) / 255f;
|
||||
mesh.a = ((color & 0x000000ff)) / 255f;
|
||||
mesh.HullLength = ReadInt(input, true) * 2;
|
||||
if (nonessential) {
|
||||
mesh.Edges = ReadIntArray(input);
|
||||
mesh.Width = ReadFloat(input) * scale;
|
||||
mesh.Height = ReadFloat(input) * scale;
|
||||
}
|
||||
return mesh;
|
||||
}
|
||||
case AttachmentType.skinnedmesh: {
|
||||
String path = ReadString(input);
|
||||
if (path == null) path = name;
|
||||
SkinnedMeshAttachment mesh = attachmentLoader.NewSkinnedMeshAttachment(skin, name, path);
|
||||
if (mesh == null) return null;
|
||||
mesh.Path = path;
|
||||
float[] uvs = ReadFloatArray(input, 1);
|
||||
int[] triangles = ReadShortArray(input);
|
||||
|
||||
int vertexCount = ReadInt(input, true);
|
||||
var weights = new List<float>(uvs.Length * 3 * 3);
|
||||
var bones = new List<int>(uvs.Length * 3);
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
int boneCount = (int)ReadFloat(input);
|
||||
bones.Add(boneCount);
|
||||
for (int nn = i + boneCount * 4; i < nn; i += 4) {
|
||||
bones.Add((int)ReadFloat(input));
|
||||
weights.Add(ReadFloat(input) * scale);
|
||||
weights.Add(ReadFloat(input) * scale);
|
||||
weights.Add(ReadFloat(input));
|
||||
}
|
||||
}
|
||||
mesh.bones = bones.ToArray();
|
||||
mesh.weights = weights.ToArray();
|
||||
mesh.triangles = triangles;
|
||||
mesh.regionUVs = uvs;
|
||||
mesh.UpdateUVs();
|
||||
int color = ReadInt(input);
|
||||
mesh.r = ((color & 0xff000000) >> 24) / 255f;
|
||||
mesh.g = ((color & 0x00ff0000) >> 16) / 255f;
|
||||
mesh.b = ((color & 0x0000ff00) >> 8) / 255f;
|
||||
mesh.a = ((color & 0x000000ff)) / 255f;
|
||||
mesh.HullLength = ReadInt(input, true) * 2;
|
||||
if (nonessential) {
|
||||
mesh.Edges = ReadIntArray(input);
|
||||
mesh.Width = ReadFloat(input) * scale;
|
||||
mesh.Height = ReadFloat(input) * scale;
|
||||
}
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private float[] ReadFloatArray (Stream input, float scale) {
|
||||
int n = ReadInt(input, true);
|
||||
float[] array = new float[n];
|
||||
if (scale == 1) {
|
||||
for (int i = 0; i < n; i++)
|
||||
array[i] = ReadFloat(input);
|
||||
} else {
|
||||
for (int i = 0; i < n; i++)
|
||||
array[i] = ReadFloat(input) * scale;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private int[] ReadShortArray (Stream input) {
|
||||
int n = ReadInt(input, true);
|
||||
int[] array = new int[n];
|
||||
for (int i = 0; i < n; i++)
|
||||
array[i] = (input.ReadByte() << 8) + input.ReadByte();
|
||||
return array;
|
||||
}
|
||||
|
||||
private int[] ReadIntArray (Stream input) {
|
||||
int n = ReadInt(input, true);
|
||||
int[] array = new int[n];
|
||||
for (int i = 0; i < n; i++)
|
||||
array[i] = ReadInt(input, true);
|
||||
return array;
|
||||
}
|
||||
|
||||
private void ReadAnimation (String name, Stream input, SkeletonData skeletonData) {
|
||||
var timelines = new List<Timeline>();
|
||||
float scale = Scale;
|
||||
float duration = 0;
|
||||
|
||||
// Slot timelines.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++) {
|
||||
int slotIndex = ReadInt(input, true);
|
||||
for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) {
|
||||
int timelineType = input.ReadByte();
|
||||
int frameCount = ReadInt(input, true);
|
||||
switch (timelineType) {
|
||||
case TIMELINE_COLOR: {
|
||||
ColorTimeline timeline = new ColorTimeline(frameCount);
|
||||
timeline.slotIndex = slotIndex;
|
||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
float time = ReadFloat(input);
|
||||
int color = ReadInt(input);
|
||||
float r = ((color & 0xff000000) >> 24) / 255f;
|
||||
float g = ((color & 0x00ff0000) >> 16) / 255f;
|
||||
float b = ((color & 0x0000ff00) >> 8) / 255f;
|
||||
float a = ((color & 0x000000ff)) / 255f;
|
||||
timeline.SetFrame(frameIndex, time, r, g, b, a);
|
||||
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[frameCount * 5 - 5]);
|
||||
break;
|
||||
}
|
||||
case TIMELINE_ATTACHMENT: {
|
||||
AttachmentTimeline timeline = new AttachmentTimeline(frameCount);
|
||||
timeline.slotIndex = slotIndex;
|
||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
|
||||
timeline.SetFrame(frameIndex, ReadFloat(input), ReadString(input));
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[frameCount - 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bone timelines.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++) {
|
||||
int boneIndex = ReadInt(input, true);
|
||||
for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) {
|
||||
int timelineType = input.ReadByte();
|
||||
int frameCount = ReadInt(input, true);
|
||||
switch (timelineType) {
|
||||
case TIMELINE_ROTATE: {
|
||||
RotateTimeline timeline = new RotateTimeline(frameCount);
|
||||
timeline.boneIndex = boneIndex;
|
||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input));
|
||||
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]);
|
||||
break;
|
||||
}
|
||||
case TIMELINE_TRANSLATE:
|
||||
case TIMELINE_SCALE: {
|
||||
TranslateTimeline timeline;
|
||||
float timelineScale = 1;
|
||||
if (timelineType == TIMELINE_SCALE)
|
||||
timeline = new ScaleTimeline(frameCount);
|
||||
else {
|
||||
timeline = new TranslateTimeline(frameCount);
|
||||
timelineScale = scale;
|
||||
}
|
||||
timeline.boneIndex = boneIndex;
|
||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input) * timelineScale, ReadFloat(input)
|
||||
* timelineScale);
|
||||
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[frameCount * 3 - 3]);
|
||||
break;
|
||||
}
|
||||
case TIMELINE_FLIPX:
|
||||
case TIMELINE_FLIPY: {
|
||||
FlipXTimeline timeline = timelineType == TIMELINE_FLIPX ? new FlipXTimeline(frameCount) : new FlipYTimeline(
|
||||
frameCount);
|
||||
timeline.boneIndex = boneIndex;
|
||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
|
||||
timeline.SetFrame(frameIndex, ReadFloat(input), ReadBoolean(input));
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[frameCount * 2 - 2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IK timelines.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++) {
|
||||
IkConstraintData ikConstraint = skeletonData.ikConstraints[ReadInt(input, true)];
|
||||
int frameCount = ReadInt(input, true);
|
||||
IkConstraintTimeline timeline = new IkConstraintTimeline(frameCount);
|
||||
timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint);
|
||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
timeline.SetFrame(frameIndex, ReadFloat(input), ReadFloat(input), ReadSByte(input));
|
||||
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[frameCount * 3 - 3]);
|
||||
}
|
||||
|
||||
// FFD timelines.
|
||||
for (int i = 0, n = ReadInt(input, true); i < n; i++) {
|
||||
Skin skin = skeletonData.skins[ReadInt(input, true)];
|
||||
for (int ii = 0, nn = ReadInt(input, true); ii < nn; ii++) {
|
||||
int slotIndex = ReadInt(input, true);
|
||||
for (int iii = 0, nnn = ReadInt(input, true); iii < nnn; iii++) {
|
||||
Attachment attachment = skin.GetAttachment(slotIndex, ReadString(input));
|
||||
int frameCount = ReadInt(input, true);
|
||||
FFDTimeline timeline = new FFDTimeline(frameCount);
|
||||
timeline.slotIndex = slotIndex;
|
||||
timeline.attachment = attachment;
|
||||
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) {
|
||||
float time = ReadFloat(input);
|
||||
|
||||
float[] vertices;
|
||||
int vertexCount;
|
||||
if (attachment is MeshAttachment)
|
||||
vertexCount = ((MeshAttachment)attachment).vertices.Length;
|
||||
else
|
||||
vertexCount = ((SkinnedMeshAttachment)attachment).weights.Length / 3 * 2;
|
||||
|
||||
int end = ReadInt(input, true);
|
||||
if (end == 0) {
|
||||
if (attachment is MeshAttachment)
|
||||
vertices = ((MeshAttachment)attachment).vertices;
|
||||
else
|
||||
vertices = new float[vertexCount];
|
||||
} else {
|
||||
vertices = new float[vertexCount];
|
||||
int start = ReadInt(input, true);
|
||||
end += start;
|
||||
if (scale == 1) {
|
||||
for (int v = start; v < end; v++)
|
||||
vertices[v] = ReadFloat(input);
|
||||
} else {
|
||||
for (int v = start; v < end; v++)
|
||||
vertices[v] = ReadFloat(input) * scale;
|
||||
}
|
||||
if (attachment is MeshAttachment) {
|
||||
float[] meshVertices = ((MeshAttachment)attachment).vertices;
|
||||
for (int v = 0, vn = vertices.Length; v < vn; v++)
|
||||
vertices[v] += meshVertices[v];
|
||||
}
|
||||
}
|
||||
|
||||
timeline.SetFrame(frameIndex, time, vertices);
|
||||
if (frameIndex < frameCount - 1) ReadCurve(input, frameIndex, timeline);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[frameCount - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw order timeline.
|
||||
int drawOrderCount = ReadInt(input, true);
|
||||
if (drawOrderCount > 0) {
|
||||
DrawOrderTimeline timeline = new DrawOrderTimeline(drawOrderCount);
|
||||
int slotCount = skeletonData.slots.Count;
|
||||
for (int i = 0; i < drawOrderCount; i++) {
|
||||
int offsetCount = ReadInt(input, true);
|
||||
int[] drawOrder = new int[slotCount];
|
||||
for (int ii = slotCount - 1; ii >= 0; ii--)
|
||||
drawOrder[ii] = -1;
|
||||
int[] unchanged = new int[slotCount - offsetCount];
|
||||
int originalIndex = 0, unchangedIndex = 0;
|
||||
for (int ii = 0; ii < offsetCount; ii++) {
|
||||
int slotIndex = ReadInt(input, true);
|
||||
// Collect unchanged items.
|
||||
while (originalIndex != slotIndex)
|
||||
unchanged[unchangedIndex++] = originalIndex++;
|
||||
// Set changed items.
|
||||
drawOrder[originalIndex + ReadInt(input, true)] = originalIndex++;
|
||||
}
|
||||
// Collect remaining unchanged items.
|
||||
while (originalIndex < slotCount)
|
||||
unchanged[unchangedIndex++] = originalIndex++;
|
||||
// Fill in unchanged items.
|
||||
for (int ii = slotCount - 1; ii >= 0; ii--)
|
||||
if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex];
|
||||
timeline.SetFrame(i, ReadFloat(input), drawOrder);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[drawOrderCount - 1]);
|
||||
}
|
||||
|
||||
// Event timeline.
|
||||
int eventCount = ReadInt(input, true);
|
||||
if (eventCount > 0) {
|
||||
EventTimeline timeline = new EventTimeline(eventCount);
|
||||
for (int i = 0; i < eventCount; i++) {
|
||||
float time = ReadFloat(input);
|
||||
EventData eventData = skeletonData.events[ReadInt(input, true)];
|
||||
Event e = new Event(eventData);
|
||||
e.Int = ReadInt(input, false);
|
||||
e.Float = ReadFloat(input);
|
||||
e.String = ReadBoolean(input) ? ReadString(input) : eventData.String;
|
||||
timeline.SetFrame(i, time, e);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[eventCount - 1]);
|
||||
}
|
||||
|
||||
timelines.TrimExcess();
|
||||
skeletonData.animations.Add(new Animation(name, timelines, duration));
|
||||
}
|
||||
|
||||
private void ReadCurve (Stream input, int frameIndex, CurveTimeline timeline) {
|
||||
switch (input.ReadByte()) {
|
||||
case CURVE_STEPPED:
|
||||
timeline.SetStepped(frameIndex);
|
||||
break;
|
||||
case CURVE_BEZIER:
|
||||
timeline.SetCurve(frameIndex, ReadFloat(input), ReadFloat(input), ReadFloat(input), ReadFloat(input));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private sbyte ReadSByte (Stream input) {
|
||||
int value = input.ReadByte();
|
||||
if (value == -1) throw new EndOfStreamException();
|
||||
return (sbyte)value;
|
||||
}
|
||||
|
||||
private bool ReadBoolean (Stream input) {
|
||||
return input.ReadByte() != 0;
|
||||
}
|
||||
|
||||
private float ReadFloat (Stream input) {
|
||||
buffer[3] = (byte)input.ReadByte();
|
||||
buffer[2] = (byte)input.ReadByte();
|
||||
buffer[1] = (byte)input.ReadByte();
|
||||
buffer[0] = (byte)input.ReadByte();
|
||||
return BitConverter.ToSingle(buffer, 0);
|
||||
}
|
||||
|
||||
private int ReadInt (Stream input) {
|
||||
return (input.ReadByte() << 24) + (input.ReadByte() << 16) + (input.ReadByte() << 8) + input.ReadByte();
|
||||
}
|
||||
|
||||
private int ReadInt (Stream input, bool optimizePositive) {
|
||||
int b = input.ReadByte();
|
||||
int result = b & 0x7F;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = input.ReadByte();
|
||||
result |= (b & 0x7F) << 7;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = input.ReadByte();
|
||||
result |= (b & 0x7F) << 14;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = input.ReadByte();
|
||||
result |= (b & 0x7F) << 21;
|
||||
if ((b & 0x80) != 0) {
|
||||
b = input.ReadByte();
|
||||
result |= (b & 0x7F) << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return optimizePositive ? result : ((result >> 1) ^ -(result & 1));
|
||||
}
|
||||
|
||||
private string ReadString (Stream input) {
|
||||
int charCount = ReadInt(input, true);
|
||||
switch (charCount) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return "";
|
||||
}
|
||||
charCount--;
|
||||
char[] chars = this.chars;
|
||||
if (chars.Length < charCount) this.chars = chars = new char[charCount];
|
||||
// Try to read 7 bit ASCII chars.
|
||||
int charIndex = 0;
|
||||
int b = 0;
|
||||
while (charIndex < charCount) {
|
||||
b = input.ReadByte();
|
||||
if (b > 127) break;
|
||||
chars[charIndex++] = (char)b;
|
||||
}
|
||||
// If a char was not ASCII, finish with slow path.
|
||||
if (charIndex < charCount) ReadUtf8_slow(input, charCount, charIndex, b);
|
||||
return new String(chars, 0, charCount);
|
||||
}
|
||||
|
||||
private void ReadUtf8_slow (Stream input, int charCount, int charIndex, int b) {
|
||||
char[] chars = this.chars;
|
||||
while (true) {
|
||||
switch (b >> 4) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
chars[charIndex] = (char)b;
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
chars[charIndex] = (char)((b & 0x1F) << 6 | input.ReadByte() & 0x3F);
|
||||
break;
|
||||
case 14:
|
||||
chars[charIndex] = (char)((b & 0x0F) << 12 | (input.ReadByte() & 0x3F) << 6 | input.ReadByte() & 0x3F);
|
||||
break;
|
||||
}
|
||||
if (++charIndex >= charCount) break;
|
||||
b = input.ReadByte() & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
215
SpineRuntimes/SpineRuntime21/SkeletonBounds.cs
Normal file
215
SpineRuntimes/SpineRuntime21/SkeletonBounds.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class SkeletonBounds {
|
||||
private List<Polygon> polygonPool = new List<Polygon>();
|
||||
private float minX, minY, maxX, maxY;
|
||||
|
||||
public List<BoundingBoxAttachment> BoundingBoxes { get; private set; }
|
||||
public List<Polygon> Polygons { get; private set; }
|
||||
public float MinX { get { return minX; } set { minX = value; } }
|
||||
public float MinY { get { return minY; } set { minY = value; } }
|
||||
public float MaxX { get { return maxX; } set { maxX = value; } }
|
||||
public float MaxY { get { return maxY; } set { maxY = value; } }
|
||||
public float Width { get { return maxX - minX; } }
|
||||
public float Height { get { return maxY - minY; } }
|
||||
|
||||
public SkeletonBounds () {
|
||||
BoundingBoxes = new List<BoundingBoxAttachment>();
|
||||
Polygons = new List<Polygon>();
|
||||
}
|
||||
|
||||
public void Update (Skeleton skeleton, bool updateAabb) {
|
||||
List<BoundingBoxAttachment> boundingBoxes = BoundingBoxes;
|
||||
List<Polygon> polygons = Polygons;
|
||||
List<Slot> slots = skeleton.slots;
|
||||
int slotCount = slots.Count;
|
||||
|
||||
boundingBoxes.Clear();
|
||||
foreach (Polygon polygon in polygons)
|
||||
polygonPool.Add(polygon);
|
||||
polygons.Clear();
|
||||
|
||||
for (int i = 0; i < slotCount; i++) {
|
||||
Slot slot = slots[i];
|
||||
BoundingBoxAttachment boundingBox = slot.attachment as BoundingBoxAttachment;
|
||||
if (boundingBox == null) continue;
|
||||
boundingBoxes.Add(boundingBox);
|
||||
|
||||
Polygon polygon = null;
|
||||
int poolCount = polygonPool.Count;
|
||||
if (poolCount > 0) {
|
||||
polygon = polygonPool[poolCount - 1];
|
||||
polygonPool.RemoveAt(poolCount - 1);
|
||||
} else
|
||||
polygon = new Polygon();
|
||||
polygons.Add(polygon);
|
||||
|
||||
int count = boundingBox.Vertices.Length;
|
||||
polygon.Count = count;
|
||||
if (polygon.Vertices.Length < count) polygon.Vertices = new float[count];
|
||||
boundingBox.ComputeWorldVertices(slot.bone, polygon.Vertices);
|
||||
}
|
||||
|
||||
if (updateAabb) aabbCompute();
|
||||
}
|
||||
|
||||
private void aabbCompute () {
|
||||
float minX = int.MaxValue, minY = int.MaxValue, maxX = int.MinValue, maxY = int.MinValue;
|
||||
List<Polygon> polygons = Polygons;
|
||||
for (int i = 0, n = polygons.Count; i < n; i++) {
|
||||
Polygon polygon = polygons[i];
|
||||
float[] vertices = polygon.Vertices;
|
||||
for (int ii = 0, nn = polygon.Count; ii < nn; ii += 2) {
|
||||
float x = vertices[ii];
|
||||
float y = vertices[ii + 1];
|
||||
minX = Math.Min(minX, x);
|
||||
minY = Math.Min(minY, y);
|
||||
maxX = Math.Max(maxX, x);
|
||||
maxY = Math.Max(maxY, y);
|
||||
}
|
||||
}
|
||||
this.minX = minX;
|
||||
this.minY = minY;
|
||||
this.maxX = maxX;
|
||||
this.maxY = maxY;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Returns true if the axis aligned bounding box contains the point.</summary>
|
||||
public bool AabbContainsPoint (float x, float y) {
|
||||
return x >= minX && x <= maxX && y >= minY && y <= maxY;
|
||||
}
|
||||
|
||||
/// <summary>Returns true if the axis aligned bounding box intersects the line segment.</summary>
|
||||
public bool AabbIntersectsSegment (float x1, float y1, float x2, float y2) {
|
||||
float minX = this.minX;
|
||||
float minY = this.minY;
|
||||
float maxX = this.maxX;
|
||||
float maxY = this.maxY;
|
||||
if ((x1 <= minX && x2 <= minX) || (y1 <= minY && y2 <= minY) || (x1 >= maxX && x2 >= maxX) || (y1 >= maxY && y2 >= maxY))
|
||||
return false;
|
||||
float m = (y2 - y1) / (x2 - x1);
|
||||
float y = m * (minX - x1) + y1;
|
||||
if (y > minY && y < maxY) return true;
|
||||
y = m * (maxX - x1) + y1;
|
||||
if (y > minY && y < maxY) return true;
|
||||
float x = (minY - y1) / m + x1;
|
||||
if (x > minX && x < maxX) return true;
|
||||
x = (maxY - y1) / m + x1;
|
||||
if (x > minX && x < maxX) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds.</summary>
|
||||
public bool AabbIntersectsSkeleton (SkeletonBounds bounds) {
|
||||
return minX < bounds.maxX && maxX > bounds.minX && minY < bounds.maxY && maxY > bounds.minY;
|
||||
}
|
||||
|
||||
/// <summary>Returns true if the polygon contains the point.</summary>
|
||||
public bool ContainsPoint (Polygon polygon, float x, float y) {
|
||||
float[] vertices = polygon.Vertices;
|
||||
int nn = polygon.Count;
|
||||
|
||||
int prevIndex = nn - 2;
|
||||
bool inside = false;
|
||||
for (int ii = 0; ii < nn; ii += 2) {
|
||||
float vertexY = vertices[ii + 1];
|
||||
float prevY = vertices[prevIndex + 1];
|
||||
if ((vertexY < y && prevY >= y) || (prevY < y && vertexY >= y)) {
|
||||
float vertexX = vertices[ii];
|
||||
if (vertexX + (y - vertexY) / (prevY - vertexY) * (vertices[prevIndex] - vertexX) < x) inside = !inside;
|
||||
}
|
||||
prevIndex = ii;
|
||||
}
|
||||
return inside;
|
||||
}
|
||||
|
||||
/// <summary>Returns the first bounding box attachment that contains the point, or null. When doing many checks, it is usually more
|
||||
/// efficient to only call this method if {@link #aabbContainsPoint(float, float)} returns true.</summary>
|
||||
public BoundingBoxAttachment ContainsPoint (float x, float y) {
|
||||
List<Polygon> polygons = Polygons;
|
||||
for (int i = 0, n = polygons.Count; i < n; i++)
|
||||
if (ContainsPoint(polygons[i], x, y)) return BoundingBoxes[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Returns the first bounding box attachment that contains the line segment, or null. When doing many checks, it is usually
|
||||
/// more efficient to only call this method if {@link #aabbIntersectsSegment(float, float, float, float)} returns true.</summary>
|
||||
public BoundingBoxAttachment IntersectsSegment (float x1, float y1, float x2, float y2) {
|
||||
List<Polygon> polygons = Polygons;
|
||||
for (int i = 0, n = polygons.Count; i < n; i++)
|
||||
if (IntersectsSegment(polygons[i], x1, y1, x2, y2)) return BoundingBoxes[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Returns true if the polygon contains the line segment.</summary>
|
||||
public bool IntersectsSegment (Polygon polygon, float x1, float y1, float x2, float y2) {
|
||||
float[] vertices = polygon.Vertices;
|
||||
int nn = polygon.Count;
|
||||
|
||||
float width12 = x1 - x2, height12 = y1 - y2;
|
||||
float det1 = x1 * y2 - y1 * x2;
|
||||
float x3 = vertices[nn - 2], y3 = vertices[nn - 1];
|
||||
for (int ii = 0; ii < nn; ii += 2) {
|
||||
float x4 = vertices[ii], y4 = vertices[ii + 1];
|
||||
float det2 = x3 * y4 - y3 * x4;
|
||||
float width34 = x3 - x4, height34 = y3 - y4;
|
||||
float det3 = width12 * height34 - height12 * width34;
|
||||
float x = (det1 * width34 - width12 * det2) / det3;
|
||||
if (((x >= x3 && x <= x4) || (x >= x4 && x <= x3)) && ((x >= x1 && x <= x2) || (x >= x2 && x <= x1))) {
|
||||
float y = (det1 * height34 - height12 * det2) / det3;
|
||||
if (((y >= y3 && y <= y4) || (y >= y4 && y <= y3)) && ((y >= y1 && y <= y2) || (y >= y2 && y <= y1))) return true;
|
||||
}
|
||||
x3 = x4;
|
||||
y3 = y4;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Polygon getPolygon (BoundingBoxAttachment attachment) {
|
||||
int index = BoundingBoxes.IndexOf(attachment);
|
||||
return index == -1 ? null : Polygons[index];
|
||||
}
|
||||
}
|
||||
|
||||
public class Polygon {
|
||||
public float[] Vertices { get; set; }
|
||||
public int Count { get; set; }
|
||||
|
||||
public Polygon () {
|
||||
Vertices = new float[16];
|
||||
}
|
||||
}
|
||||
}
|
||||
158
SpineRuntimes/SpineRuntime21/SkeletonData.cs
Normal file
158
SpineRuntimes/SpineRuntime21/SkeletonData.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class SkeletonData {
|
||||
internal String name;
|
||||
internal List<BoneData> bones = new List<BoneData>();
|
||||
internal List<SlotData> slots = new List<SlotData>();
|
||||
internal List<Skin> skins = new List<Skin>();
|
||||
internal Skin defaultSkin;
|
||||
internal List<EventData> events = new List<EventData>();
|
||||
internal List<Animation> animations = new List<Animation>();
|
||||
internal List<IkConstraintData> ikConstraints = new List<IkConstraintData>();
|
||||
internal float width, height;
|
||||
internal String version, hash, imagesPath;
|
||||
|
||||
public String Name { get { return name; } set { name = value; } }
|
||||
public List<BoneData> Bones { get { return bones; } } // Ordered parents first.
|
||||
public List<SlotData> Slots { get { return slots; } } // Setup pose draw order.
|
||||
public List<Skin> Skins { get { return skins; } set { skins = value; } }
|
||||
/// <summary>May be null.</summary>
|
||||
public Skin DefaultSkin { get { return defaultSkin; } set { defaultSkin = value; } }
|
||||
public List<EventData> Events { get { return events; } set { events = value; } }
|
||||
public List<Animation> Animations { get { return animations; } set { animations = value; } }
|
||||
public List<IkConstraintData> IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } }
|
||||
public float Width { get { return width; } set { width = value; } }
|
||||
public float Height { get { return height; } set { height = value; } }
|
||||
/// <summary>The Spine version used to export this data.</summary>
|
||||
public String Version { get { return version; } set { version = value; } }
|
||||
public String Hash { get { return hash; } set { hash = value; } }
|
||||
|
||||
// --- Bones.
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public BoneData FindBone (String boneName) {
|
||||
if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
|
||||
List<BoneData> bones = this.bones;
|
||||
for (int i = 0, n = bones.Count; i < n; i++) {
|
||||
BoneData bone = bones[i];
|
||||
if (bone.name == boneName) return bone;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <returns>-1 if the bone was not found.</returns>
|
||||
public int FindBoneIndex (String boneName) {
|
||||
if (boneName == null) throw new ArgumentNullException("boneName cannot be null.");
|
||||
List<BoneData> bones = this.bones;
|
||||
for (int i = 0, n = bones.Count; i < n; i++)
|
||||
if (bones[i].name == boneName) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// --- Slots.
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public SlotData FindSlot (String slotName) {
|
||||
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
|
||||
List<SlotData> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++) {
|
||||
SlotData slot = slots[i];
|
||||
if (slot.name == slotName) return slot;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <returns>-1 if the bone was not found.</returns>
|
||||
public int FindSlotIndex (String slotName) {
|
||||
if (slotName == null) throw new ArgumentNullException("slotName cannot be null.");
|
||||
List<SlotData> slots = this.slots;
|
||||
for (int i = 0, n = slots.Count; i < n; i++)
|
||||
if (slots[i].name == slotName) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// --- Skins.
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Skin FindSkin (String skinName) {
|
||||
if (skinName == null) throw new ArgumentNullException("skinName cannot be null.");
|
||||
foreach (Skin skin in skins)
|
||||
if (skin.name == skinName) return skin;
|
||||
return null;
|
||||
}
|
||||
|
||||
// --- Events.
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public EventData FindEvent (String eventDataName) {
|
||||
if (eventDataName == null) throw new ArgumentNullException("eventDataName cannot be null.");
|
||||
foreach (EventData eventData in events)
|
||||
if (eventData.name == eventDataName) return eventData;
|
||||
return null;
|
||||
}
|
||||
|
||||
// --- Animations.
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Animation FindAnimation (String animationName) {
|
||||
if (animationName == null) throw new ArgumentNullException("animationName cannot be null.");
|
||||
List<Animation> animations = this.animations;
|
||||
for (int i = 0, n = animations.Count; i < n; i++) {
|
||||
Animation animation = animations[i];
|
||||
if (animation.name == animationName) return animation;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// --- IK constraints.
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public IkConstraintData FindIkConstraint (String ikConstraintName) {
|
||||
if (ikConstraintName == null) throw new ArgumentNullException("ikConstraintName cannot be null.");
|
||||
List<IkConstraintData> ikConstraints = this.ikConstraints;
|
||||
for (int i = 0, n = ikConstraints.Count; i < n; i++) {
|
||||
IkConstraintData ikConstraint = ikConstraints[i];
|
||||
if (ikConstraint.name == ikConstraintName) return ikConstraint;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
override public String ToString () {
|
||||
return name ?? base.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
641
SpineRuntimes/SpineRuntime21/SkeletonJson.cs
Normal file
641
SpineRuntimes/SpineRuntime21/SkeletonJson.cs
Normal file
@@ -0,0 +1,641 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if WINDOWS_STOREAPP
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
#endif
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class SkeletonJson {
|
||||
private AttachmentLoader attachmentLoader;
|
||||
public float Scale { get; set; }
|
||||
|
||||
public SkeletonJson (params Atlas[] atlasArray)
|
||||
: this(new AtlasAttachmentLoader(atlasArray)) {
|
||||
}
|
||||
|
||||
public SkeletonJson (AttachmentLoader attachmentLoader) {
|
||||
if (attachmentLoader == null) throw new ArgumentNullException("attachmentLoader cannot be null.");
|
||||
this.attachmentLoader = attachmentLoader;
|
||||
Scale = 1;
|
||||
}
|
||||
|
||||
#if WINDOWS_STOREAPP
|
||||
private async Task<SkeletonData> ReadFile(string path) {
|
||||
var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
|
||||
var file = await folder.GetFileAsync(path).AsTask().ConfigureAwait(false);
|
||||
using (var reader = new StreamReader(await file.OpenStreamForReadAsync().ConfigureAwait(false))) {
|
||||
SkeletonData skeletonData = ReadSkeletonData(reader);
|
||||
skeletonData.Name = Path.GetFileNameWithoutExtension(path);
|
||||
return skeletonData;
|
||||
}
|
||||
}
|
||||
|
||||
public SkeletonData ReadSkeletonData (String path) {
|
||||
return this.ReadFile(path).Result;
|
||||
}
|
||||
#else
|
||||
public SkeletonData ReadSkeletonData (String path) {
|
||||
#if WINDOWS_PHONE
|
||||
Stream stream = Microsoft.Xna.Framework.TitleContainer.OpenStream(path);
|
||||
using (StreamReader reader = new StreamReader(stream)) {
|
||||
#else
|
||||
using (StreamReader reader = new StreamReader(path)) {
|
||||
#endif
|
||||
SkeletonData skeletonData = ReadSkeletonData(reader);
|
||||
skeletonData.name = Path.GetFileNameWithoutExtension(path);
|
||||
return skeletonData;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public SkeletonData ReadSkeletonData (TextReader reader) {
|
||||
if (reader == null) throw new ArgumentNullException("reader cannot be null.");
|
||||
|
||||
var skeletonData = new SkeletonData();
|
||||
|
||||
var root = Json.Deserialize(reader) as Dictionary<String, Object>;
|
||||
if (root == null) throw new Exception("Invalid JSON.");
|
||||
|
||||
// Skeleton.
|
||||
if (root.ContainsKey("skeleton")) {
|
||||
var skeletonMap = (Dictionary<String, Object>)root["skeleton"];
|
||||
skeletonData.hash = (String)skeletonMap["hash"];
|
||||
skeletonData.version = (String)skeletonMap["spine"];
|
||||
skeletonData.width = GetFloat(skeletonMap, "width", 0);
|
||||
skeletonData.height = GetFloat(skeletonMap, "height", 0);
|
||||
}
|
||||
|
||||
// Bones.
|
||||
foreach (Dictionary<String, Object> boneMap in (List<Object>)root["bones"]) {
|
||||
BoneData parent = null;
|
||||
if (boneMap.ContainsKey("parent")) {
|
||||
parent = skeletonData.FindBone((String)boneMap["parent"]);
|
||||
if (parent == null)
|
||||
throw new Exception("Parent bone not found: " + boneMap["parent"]);
|
||||
}
|
||||
var boneData = new BoneData((String)boneMap["name"], parent);
|
||||
boneData.length = GetFloat(boneMap, "length", 0) * Scale;
|
||||
boneData.x = GetFloat(boneMap, "x", 0) * Scale;
|
||||
boneData.y = GetFloat(boneMap, "y", 0) * Scale;
|
||||
boneData.rotation = GetFloat(boneMap, "rotation", 0);
|
||||
boneData.scaleX = GetFloat(boneMap, "scaleX", 1);
|
||||
boneData.scaleY = GetFloat(boneMap, "scaleY", 1);
|
||||
boneData.flipX = GetBoolean(boneMap, "flipX", false);
|
||||
boneData.flipY = GetBoolean(boneMap, "flipY", false);
|
||||
boneData.inheritScale = GetBoolean(boneMap, "inheritScale", true);
|
||||
boneData.inheritRotation = GetBoolean(boneMap, "inheritRotation", true);
|
||||
skeletonData.bones.Add(boneData);
|
||||
}
|
||||
|
||||
// IK constraints.
|
||||
if (root.ContainsKey("ik")) {
|
||||
foreach (Dictionary<String, Object> ikMap in (List<Object>)root["ik"]) {
|
||||
IkConstraintData ikConstraintData = new IkConstraintData((String)ikMap["name"]);
|
||||
|
||||
foreach (String boneName in (List<Object>)ikMap["bones"]) {
|
||||
BoneData bone = skeletonData.FindBone(boneName);
|
||||
if (bone == null) throw new Exception("IK bone not found: " + boneName);
|
||||
ikConstraintData.bones.Add(bone);
|
||||
}
|
||||
|
||||
String targetName = (String)ikMap["target"];
|
||||
ikConstraintData.target = skeletonData.FindBone(targetName);
|
||||
if (ikConstraintData.target == null) throw new Exception("Target bone not found: " + targetName);
|
||||
|
||||
ikConstraintData.bendDirection = GetBoolean(ikMap, "bendPositive", true) ? 1 : -1;
|
||||
ikConstraintData.mix = GetFloat(ikMap, "mix", 1);
|
||||
|
||||
skeletonData.ikConstraints.Add(ikConstraintData);
|
||||
}
|
||||
}
|
||||
|
||||
// Slots.
|
||||
if (root.ContainsKey("slots")) {
|
||||
foreach (Dictionary<String, Object> slotMap in (List<Object>)root["slots"]) {
|
||||
var slotName = (String)slotMap["name"];
|
||||
var boneName = (String)slotMap["bone"];
|
||||
BoneData boneData = skeletonData.FindBone(boneName);
|
||||
if (boneData == null)
|
||||
throw new Exception("Slot bone not found: " + boneName);
|
||||
var slotData = new SlotData(slotName, boneData);
|
||||
|
||||
if (slotMap.ContainsKey("color")) {
|
||||
var color = (String)slotMap["color"];
|
||||
slotData.r = ToColor(color, 0);
|
||||
slotData.g = ToColor(color, 1);
|
||||
slotData.b = ToColor(color, 2);
|
||||
slotData.a = ToColor(color, 3);
|
||||
}
|
||||
|
||||
if (slotMap.ContainsKey("attachment"))
|
||||
slotData.attachmentName = (String)slotMap["attachment"];
|
||||
|
||||
if (slotMap.ContainsKey("additive"))
|
||||
slotData.additiveBlending = (bool)slotMap["additive"];
|
||||
|
||||
skeletonData.slots.Add(slotData);
|
||||
}
|
||||
}
|
||||
|
||||
// Skins.
|
||||
if (root.ContainsKey("skins")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["skins"]) {
|
||||
var skin = new Skin(entry.Key);
|
||||
foreach (KeyValuePair<String, Object> slotEntry in (Dictionary<String, Object>)entry.Value) {
|
||||
int slotIndex = skeletonData.FindSlotIndex(slotEntry.Key);
|
||||
foreach (KeyValuePair<String, Object> attachmentEntry in ((Dictionary<String, Object>)slotEntry.Value)) {
|
||||
Attachment attachment = ReadAttachment(skin, attachmentEntry.Key, (Dictionary<String, Object>)attachmentEntry.Value);
|
||||
if (attachment != null) skin.AddAttachment(slotIndex, attachmentEntry.Key, attachment);
|
||||
}
|
||||
}
|
||||
skeletonData.skins.Add(skin);
|
||||
if (skin.name == "default")
|
||||
skeletonData.defaultSkin = skin;
|
||||
}
|
||||
}
|
||||
|
||||
// Events.
|
||||
if (root.ContainsKey("events")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["events"]) {
|
||||
var entryMap = (Dictionary<String, Object>)entry.Value;
|
||||
var eventData = new EventData(entry.Key);
|
||||
eventData.Int = GetInt(entryMap, "int", 0);
|
||||
eventData.Float = GetFloat(entryMap, "float", 0);
|
||||
eventData.String = GetString(entryMap, "string", null);
|
||||
skeletonData.events.Add(eventData);
|
||||
}
|
||||
}
|
||||
|
||||
// Animations.
|
||||
if (root.ContainsKey("animations")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)root["animations"])
|
||||
ReadAnimation(entry.Key, (Dictionary<String, Object>)entry.Value, skeletonData);
|
||||
}
|
||||
|
||||
skeletonData.bones.TrimExcess();
|
||||
skeletonData.slots.TrimExcess();
|
||||
skeletonData.skins.TrimExcess();
|
||||
skeletonData.events.TrimExcess();
|
||||
skeletonData.animations.TrimExcess();
|
||||
skeletonData.ikConstraints.TrimExcess();
|
||||
return skeletonData;
|
||||
}
|
||||
|
||||
private Attachment ReadAttachment (Skin skin, String name, Dictionary<String, Object> map) {
|
||||
if (map.ContainsKey("name"))
|
||||
name = (String)map["name"];
|
||||
|
||||
var type = AttachmentType.region;
|
||||
if (map.ContainsKey("type"))
|
||||
type = (AttachmentType)Enum.Parse(typeof(AttachmentType), (String)map["type"], false);
|
||||
|
||||
String path = name;
|
||||
if (map.ContainsKey("path"))
|
||||
path = (String)map["path"];
|
||||
|
||||
switch (type) {
|
||||
case AttachmentType.region:
|
||||
RegionAttachment region = attachmentLoader.NewRegionAttachment(skin, name, path);
|
||||
if (region == null) return null;
|
||||
region.Path = path;
|
||||
region.x = GetFloat(map, "x", 0) * Scale;
|
||||
region.y = GetFloat(map, "y", 0) * Scale;
|
||||
region.scaleX = GetFloat(map, "scaleX", 1);
|
||||
region.scaleY = GetFloat(map, "scaleY", 1);
|
||||
region.rotation = GetFloat(map, "rotation", 0);
|
||||
region.width = GetFloat(map, "width", 32) * Scale;
|
||||
region.height = GetFloat(map, "height", 32) * Scale;
|
||||
region.UpdateOffset();
|
||||
|
||||
if (map.ContainsKey("color")) {
|
||||
var color = (String)map["color"];
|
||||
region.r = ToColor(color, 0);
|
||||
region.g = ToColor(color, 1);
|
||||
region.b = ToColor(color, 2);
|
||||
region.a = ToColor(color, 3);
|
||||
}
|
||||
|
||||
return region;
|
||||
case AttachmentType.mesh: {
|
||||
MeshAttachment mesh = attachmentLoader.NewMeshAttachment(skin, name, path);
|
||||
if (mesh == null) return null;
|
||||
|
||||
mesh.Path = path;
|
||||
mesh.vertices = GetFloatArray(map, "vertices", Scale);
|
||||
mesh.triangles = GetIntArray(map, "triangles");
|
||||
mesh.regionUVs = GetFloatArray(map, "uvs", 1);
|
||||
mesh.UpdateUVs();
|
||||
|
||||
if (map.ContainsKey("color")) {
|
||||
var color = (String)map["color"];
|
||||
mesh.r = ToColor(color, 0);
|
||||
mesh.g = ToColor(color, 1);
|
||||
mesh.b = ToColor(color, 2);
|
||||
mesh.a = ToColor(color, 3);
|
||||
}
|
||||
|
||||
mesh.HullLength = GetInt(map, "hull", 0) * 2;
|
||||
if (map.ContainsKey("edges")) mesh.Edges = GetIntArray(map, "edges");
|
||||
mesh.Width = GetInt(map, "width", 0) * Scale;
|
||||
mesh.Height = GetInt(map, "height", 0) * Scale;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
case AttachmentType.skinnedmesh: {
|
||||
SkinnedMeshAttachment mesh = attachmentLoader.NewSkinnedMeshAttachment(skin, name, path);
|
||||
if (mesh == null) return null;
|
||||
|
||||
mesh.Path = path;
|
||||
float[] uvs = GetFloatArray(map, "uvs", 1);
|
||||
float[] vertices = GetFloatArray(map, "vertices", 1);
|
||||
var weights = new List<float>(uvs.Length * 3 * 3);
|
||||
var bones = new List<int>(uvs.Length * 3);
|
||||
float scale = Scale;
|
||||
for (int i = 0, n = vertices.Length; i < n; ) {
|
||||
int boneCount = (int)vertices[i++];
|
||||
bones.Add(boneCount);
|
||||
for (int nn = i + boneCount * 4; i < nn; ) {
|
||||
bones.Add((int)vertices[i]);
|
||||
weights.Add(vertices[i + 1] * scale);
|
||||
weights.Add(vertices[i + 2] * scale);
|
||||
weights.Add(vertices[i + 3]);
|
||||
i += 4;
|
||||
}
|
||||
}
|
||||
mesh.bones = bones.ToArray();
|
||||
mesh.weights = weights.ToArray();
|
||||
mesh.triangles = GetIntArray(map, "triangles");
|
||||
mesh.regionUVs = uvs;
|
||||
mesh.UpdateUVs();
|
||||
|
||||
if (map.ContainsKey("color")) {
|
||||
var color = (String)map["color"];
|
||||
mesh.r = ToColor(color, 0);
|
||||
mesh.g = ToColor(color, 1);
|
||||
mesh.b = ToColor(color, 2);
|
||||
mesh.a = ToColor(color, 3);
|
||||
}
|
||||
|
||||
mesh.HullLength = GetInt(map, "hull", 0) * 2;
|
||||
if (map.ContainsKey("edges")) mesh.Edges = GetIntArray(map, "edges");
|
||||
mesh.Width = GetInt(map, "width", 0) * Scale;
|
||||
mesh.Height = GetInt(map, "height", 0) * Scale;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
case AttachmentType.boundingbox:
|
||||
BoundingBoxAttachment box = attachmentLoader.NewBoundingBoxAttachment(skin, name);
|
||||
if (box == null) return null;
|
||||
box.vertices = GetFloatArray(map, "vertices", Scale);
|
||||
return box;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private float[] GetFloatArray (Dictionary<String, Object> map, String name, float scale) {
|
||||
var list = (List<Object>)map[name];
|
||||
var values = new float[list.Count];
|
||||
if (scale == 1) {
|
||||
for (int i = 0, n = list.Count; i < n; i++)
|
||||
values[i] = (float)list[i];
|
||||
} else {
|
||||
for (int i = 0, n = list.Count; i < n; i++)
|
||||
values[i] = (float)list[i] * scale;
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private int[] GetIntArray (Dictionary<String, Object> map, String name) {
|
||||
var list = (List<Object>)map[name];
|
||||
var values = new int[list.Count];
|
||||
for (int i = 0, n = list.Count; i < n; i++)
|
||||
values[i] = (int)(float)list[i];
|
||||
return values;
|
||||
}
|
||||
|
||||
private float GetFloat (Dictionary<String, Object> map, String name, float defaultValue) {
|
||||
if (!map.ContainsKey(name))
|
||||
return defaultValue;
|
||||
return (float)map[name];
|
||||
}
|
||||
|
||||
private int GetInt (Dictionary<String, Object> map, String name, int defaultValue) {
|
||||
if (!map.ContainsKey(name))
|
||||
return defaultValue;
|
||||
return (int)(float)map[name];
|
||||
}
|
||||
|
||||
private bool GetBoolean (Dictionary<String, Object> map, String name, bool defaultValue) {
|
||||
if (!map.ContainsKey(name))
|
||||
return defaultValue;
|
||||
return (bool)map[name];
|
||||
}
|
||||
|
||||
private String GetString (Dictionary<String, Object> map, String name, String defaultValue) {
|
||||
if (!map.ContainsKey(name))
|
||||
return defaultValue;
|
||||
return (String)map[name];
|
||||
}
|
||||
|
||||
private float ToColor (String hexString, int colorIndex) {
|
||||
if (hexString.Length != 8)
|
||||
throw new ArgumentException("Color hexidecimal length must be 8, recieved: " + hexString);
|
||||
return Convert.ToInt32(hexString.Substring(colorIndex * 2, 2), 16) / (float)255;
|
||||
}
|
||||
|
||||
private void ReadAnimation (String name, Dictionary<String, Object> map, SkeletonData skeletonData) {
|
||||
var timelines = new List<Timeline>();
|
||||
float duration = 0;
|
||||
float scale = Scale;
|
||||
|
||||
if (map.ContainsKey("slots")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["slots"]) {
|
||||
String slotName = entry.Key;
|
||||
int slotIndex = skeletonData.FindSlotIndex(slotName);
|
||||
var timelineMap = (Dictionary<String, Object>)entry.Value;
|
||||
|
||||
foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
|
||||
var values = (List<Object>)timelineEntry.Value;
|
||||
var timelineName = (String)timelineEntry.Key;
|
||||
if (timelineName == "color") {
|
||||
var timeline = new ColorTimeline(values.Count);
|
||||
timeline.slotIndex = slotIndex;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
String c = (String)valueMap["color"];
|
||||
timeline.SetFrame(frameIndex, time, ToColor(c, 0), ToColor(c, 1), ToColor(c, 2), ToColor(c, 3));
|
||||
ReadCurve(timeline, frameIndex, valueMap);
|
||||
frameIndex++;
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 5 - 5]);
|
||||
|
||||
} else if (timelineName == "attachment") {
|
||||
var timeline = new AttachmentTimeline(values.Count);
|
||||
timeline.slotIndex = slotIndex;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
timeline.SetFrame(frameIndex++, time, (String)valueMap["name"]);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
|
||||
|
||||
} else
|
||||
throw new Exception("Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (map.ContainsKey("bones")) {
|
||||
foreach (KeyValuePair<String, Object> entry in (Dictionary<String, Object>)map["bones"]) {
|
||||
String boneName = entry.Key;
|
||||
int boneIndex = skeletonData.FindBoneIndex(boneName);
|
||||
if (boneIndex == -1)
|
||||
throw new Exception("Bone not found: " + boneName);
|
||||
|
||||
var timelineMap = (Dictionary<String, Object>)entry.Value;
|
||||
foreach (KeyValuePair<String, Object> timelineEntry in timelineMap) {
|
||||
var values = (List<Object>)timelineEntry.Value;
|
||||
var timelineName = (String)timelineEntry.Key;
|
||||
if (timelineName == "rotate") {
|
||||
var timeline = new RotateTimeline(values.Count);
|
||||
timeline.boneIndex = boneIndex;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
timeline.SetFrame(frameIndex, time, (float)valueMap["angle"]);
|
||||
ReadCurve(timeline, frameIndex, valueMap);
|
||||
frameIndex++;
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]);
|
||||
|
||||
} else if (timelineName == "translate" || timelineName == "scale") {
|
||||
TranslateTimeline timeline;
|
||||
float timelineScale = 1;
|
||||
if (timelineName == "scale")
|
||||
timeline = new ScaleTimeline(values.Count);
|
||||
else {
|
||||
timeline = new TranslateTimeline(values.Count);
|
||||
timelineScale = scale;
|
||||
}
|
||||
timeline.boneIndex = boneIndex;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
float x = valueMap.ContainsKey("x") ? (float)valueMap["x"] : 0;
|
||||
float y = valueMap.ContainsKey("y") ? (float)valueMap["y"] : 0;
|
||||
timeline.SetFrame(frameIndex, time, (float)x * timelineScale, (float)y * timelineScale);
|
||||
ReadCurve(timeline, frameIndex, valueMap);
|
||||
frameIndex++;
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]);
|
||||
|
||||
} else if (timelineName == "flipX" || timelineName == "flipY") {
|
||||
bool x = timelineName == "flipX";
|
||||
var timeline = x ? new FlipXTimeline(values.Count) : new FlipYTimeline(values.Count);
|
||||
timeline.boneIndex = boneIndex;
|
||||
|
||||
String field = x ? "x" : "y";
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
timeline.SetFrame(frameIndex, time, valueMap.ContainsKey(field) ? (bool)valueMap[field] : false);
|
||||
frameIndex++;
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 2 - 2]);
|
||||
|
||||
} else
|
||||
throw new Exception("Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (map.ContainsKey("ik")) {
|
||||
foreach (KeyValuePair<String, Object> ikMap in (Dictionary<String, Object>)map["ik"]) {
|
||||
IkConstraintData ikConstraint = skeletonData.FindIkConstraint(ikMap.Key);
|
||||
var values = (List<Object>)ikMap.Value;
|
||||
var timeline = new IkConstraintTimeline(values.Count);
|
||||
timeline.ikConstraintIndex = skeletonData.ikConstraints.IndexOf(ikConstraint);
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
float time = (float)valueMap["time"];
|
||||
float mix = valueMap.ContainsKey("mix") ? (float)valueMap["mix"] : 1;
|
||||
bool bendPositive = valueMap.ContainsKey("bendPositive") ? (bool)valueMap["bendPositive"] : true;
|
||||
timeline.SetFrame(frameIndex, time, mix, bendPositive ? 1 : -1);
|
||||
ReadCurve(timeline, frameIndex, valueMap);
|
||||
frameIndex++;
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount * 3 - 3]);
|
||||
}
|
||||
}
|
||||
|
||||
if (map.ContainsKey("ffd")) {
|
||||
foreach (KeyValuePair<String, Object> ffdMap in (Dictionary<String, Object>)map["ffd"]) {
|
||||
Skin skin = skeletonData.FindSkin(ffdMap.Key);
|
||||
foreach (KeyValuePair<String, Object> slotMap in (Dictionary<String, Object>)ffdMap.Value) {
|
||||
int slotIndex = skeletonData.FindSlotIndex(slotMap.Key);
|
||||
foreach (KeyValuePair<String, Object> meshMap in (Dictionary<String, Object>)slotMap.Value) {
|
||||
var values = (List<Object>)meshMap.Value;
|
||||
var timeline = new FFDTimeline(values.Count);
|
||||
Attachment attachment = skin.GetAttachment(slotIndex, meshMap.Key);
|
||||
if (attachment == null) throw new Exception("FFD attachment not found: " + meshMap.Key);
|
||||
timeline.slotIndex = slotIndex;
|
||||
timeline.attachment = attachment;
|
||||
|
||||
int vertexCount;
|
||||
if (attachment is MeshAttachment)
|
||||
vertexCount = ((MeshAttachment)attachment).vertices.Length;
|
||||
else
|
||||
vertexCount = ((SkinnedMeshAttachment)attachment).Weights.Length / 3 * 2;
|
||||
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> valueMap in values) {
|
||||
float[] vertices;
|
||||
if (!valueMap.ContainsKey("vertices")) {
|
||||
if (attachment is MeshAttachment)
|
||||
vertices = ((MeshAttachment)attachment).vertices;
|
||||
else
|
||||
vertices = new float[vertexCount];
|
||||
} else {
|
||||
var verticesValue = (List<Object>)valueMap["vertices"];
|
||||
vertices = new float[vertexCount];
|
||||
int start = GetInt(valueMap, "offset", 0);
|
||||
if (scale == 1) {
|
||||
for (int i = 0, n = verticesValue.Count; i < n; i++)
|
||||
vertices[i + start] = (float)verticesValue[i];
|
||||
} else {
|
||||
for (int i = 0, n = verticesValue.Count; i < n; i++)
|
||||
vertices[i + start] = (float)verticesValue[i] * scale;
|
||||
}
|
||||
if (attachment is MeshAttachment) {
|
||||
float[] meshVertices = ((MeshAttachment)attachment).vertices;
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
vertices[i] += meshVertices[i];
|
||||
}
|
||||
}
|
||||
|
||||
timeline.SetFrame(frameIndex, (float)valueMap["time"], vertices);
|
||||
ReadCurve(timeline, frameIndex, valueMap);
|
||||
frameIndex++;
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (map.ContainsKey("drawOrder") || map.ContainsKey("draworder")) {
|
||||
var values = (List<Object>)map[map.ContainsKey("drawOrder") ? "drawOrder" : "draworder"];
|
||||
var timeline = new DrawOrderTimeline(values.Count);
|
||||
int slotCount = skeletonData.slots.Count;
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> drawOrderMap in values) {
|
||||
int[] drawOrder = null;
|
||||
if (drawOrderMap.ContainsKey("offsets")) {
|
||||
drawOrder = new int[slotCount];
|
||||
for (int i = slotCount - 1; i >= 0; i--)
|
||||
drawOrder[i] = -1;
|
||||
var offsets = (List<Object>)drawOrderMap["offsets"];
|
||||
int[] unchanged = new int[slotCount - offsets.Count];
|
||||
int originalIndex = 0, unchangedIndex = 0;
|
||||
foreach (Dictionary<String, Object> offsetMap in offsets) {
|
||||
int slotIndex = skeletonData.FindSlotIndex((String)offsetMap["slot"]);
|
||||
if (slotIndex == -1) throw new Exception("Slot not found: " + offsetMap["slot"]);
|
||||
// Collect unchanged items.
|
||||
while (originalIndex != slotIndex)
|
||||
unchanged[unchangedIndex++] = originalIndex++;
|
||||
// Set changed items.
|
||||
int index = originalIndex + (int)(float)offsetMap["offset"];
|
||||
drawOrder[index] = originalIndex++;
|
||||
}
|
||||
// Collect remaining unchanged items.
|
||||
while (originalIndex < slotCount)
|
||||
unchanged[unchangedIndex++] = originalIndex++;
|
||||
// Fill in unchanged items.
|
||||
for (int i = slotCount - 1; i >= 0; i--)
|
||||
if (drawOrder[i] == -1) drawOrder[i] = unchanged[--unchangedIndex];
|
||||
}
|
||||
timeline.SetFrame(frameIndex++, (float)drawOrderMap["time"], drawOrder);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
|
||||
}
|
||||
|
||||
if (map.ContainsKey("events")) {
|
||||
var eventsMap = (List<Object>)map["events"];
|
||||
var timeline = new EventTimeline(eventsMap.Count);
|
||||
int frameIndex = 0;
|
||||
foreach (Dictionary<String, Object> eventMap in eventsMap) {
|
||||
EventData eventData = skeletonData.FindEvent((String)eventMap["name"]);
|
||||
if (eventData == null) throw new Exception("Event not found: " + eventMap["name"]);
|
||||
var e = new Event(eventData);
|
||||
e.Int = GetInt(eventMap, "int", eventData.Int);
|
||||
e.Float = GetFloat(eventMap, "float", eventData.Float);
|
||||
e.String = GetString(eventMap, "string", eventData.String);
|
||||
timeline.SetFrame(frameIndex++, (float)eventMap["time"], e);
|
||||
}
|
||||
timelines.Add(timeline);
|
||||
duration = Math.Max(duration, timeline.frames[timeline.FrameCount - 1]);
|
||||
}
|
||||
|
||||
timelines.TrimExcess();
|
||||
skeletonData.animations.Add(new Animation(name, timelines, duration));
|
||||
}
|
||||
|
||||
private void ReadCurve (CurveTimeline timeline, int frameIndex, Dictionary<String, Object> valueMap) {
|
||||
if (!valueMap.ContainsKey("curve"))
|
||||
return;
|
||||
Object curveObject = valueMap["curve"];
|
||||
if (curveObject.Equals("stepped"))
|
||||
timeline.SetStepped(frameIndex);
|
||||
else if (curveObject is List<Object>) {
|
||||
var curve = (List<Object>)curveObject;
|
||||
timeline.SetCurve(frameIndex, (float)curve[0], (float)curve[1], (float)curve[2], (float)curve[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
102
SpineRuntimes/SpineRuntime21/Skin.cs
Normal file
102
SpineRuntimes/SpineRuntime21/Skin.cs
Normal file
@@ -0,0 +1,102 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
/// <summary>Stores attachments by slot index and attachment name.</summary>
|
||||
public class Skin {
|
||||
internal String name;
|
||||
private Dictionary<KeyValuePair<int, String>, Attachment> attachments =
|
||||
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) {
|
||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void AddAttachment (int slotIndex, String name, Attachment attachment) {
|
||||
if (attachment == null) throw new ArgumentNullException("attachment cannot be null.");
|
||||
attachments[new KeyValuePair<int, String>(slotIndex, name)] = attachment;
|
||||
}
|
||||
|
||||
/// <returns>May be null.</returns>
|
||||
public Attachment GetAttachment (int slotIndex, String name) {
|
||||
Attachment attachment;
|
||||
attachments.TryGetValue(new KeyValuePair<int, String>(slotIndex, name), out attachment);
|
||||
return attachment;
|
||||
}
|
||||
|
||||
public void FindNamesForSlot (int slotIndex, List<String> names) {
|
||||
if (names == null) throw new ArgumentNullException("names cannot be null.");
|
||||
foreach (KeyValuePair<int, String> key in attachments.Keys)
|
||||
if (key.Key == slotIndex) names.Add(key.Value);
|
||||
}
|
||||
|
||||
public void FindAttachmentsForSlot (int slotIndex, List<Attachment> attachments) {
|
||||
if (attachments == null) throw new ArgumentNullException("attachments cannot be null.");
|
||||
foreach (KeyValuePair<KeyValuePair<int, String>, Attachment> entry in this.attachments)
|
||||
if (entry.Key.Key == slotIndex) attachments.Add(entry.Value);
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return name;
|
||||
}
|
||||
|
||||
/// <summary>Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached.</summary>
|
||||
internal void AttachAll (Skeleton skeleton, Skin oldSkin) {
|
||||
foreach (KeyValuePair<KeyValuePair<int, String>, Attachment> entry in oldSkin.attachments) {
|
||||
int slotIndex = entry.Key.Key;
|
||||
Slot slot = skeleton.slots[slotIndex];
|
||||
if (slot.attachment == entry.Value) {
|
||||
Attachment attachment = GetAttachment(slotIndex, entry.Key.Value);
|
||||
if (attachment != null) slot.Attachment = attachment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Avoids boxing in the dictionary.
|
||||
private class AttachmentComparer : IEqualityComparer<KeyValuePair<int, String>> {
|
||||
internal static readonly AttachmentComparer Instance = new AttachmentComparer();
|
||||
|
||||
bool IEqualityComparer<KeyValuePair<int, string>>.Equals (KeyValuePair<int, string> o1, KeyValuePair<int, string> o2) {
|
||||
return o1.Key == o2.Key && o1.Value == o2.Value;
|
||||
}
|
||||
|
||||
int IEqualityComparer<KeyValuePair<int, string>>.GetHashCode (KeyValuePair<int, string> o) {
|
||||
return o.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
99
SpineRuntimes/SpineRuntime21/Slot.cs
Normal file
99
SpineRuntimes/SpineRuntime21/Slot.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class Slot {
|
||||
internal SlotData data;
|
||||
internal Bone bone;
|
||||
internal float r, g, b, a;
|
||||
internal Attachment attachment;
|
||||
internal float attachmentTime;
|
||||
internal float[] attachmentVertices = new float[0];
|
||||
internal int attachmentVerticesCount;
|
||||
|
||||
public SlotData Data { get { return data; } }
|
||||
public Bone Bone { get { return bone; } }
|
||||
public Skeleton Skeleton { get { return bone.skeleton; } }
|
||||
public float R { get { return r; } set { r = value; } }
|
||||
public float G { get { return g; } set { g = value; } }
|
||||
public float B { get { return b; } set { b = value; } }
|
||||
public float A { get { return a; } set { a = value; } }
|
||||
|
||||
/// <summary>May be null.</summary>
|
||||
public Attachment Attachment {
|
||||
get {
|
||||
return attachment;
|
||||
}
|
||||
set {
|
||||
attachment = value;
|
||||
attachmentTime = bone.skeleton.time;
|
||||
attachmentVerticesCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public float AttachmentTime {
|
||||
get {
|
||||
return bone.skeleton.time - attachmentTime;
|
||||
}
|
||||
set {
|
||||
attachmentTime = bone.skeleton.time - value;
|
||||
}
|
||||
}
|
||||
|
||||
public float[] AttachmentVertices { get { return attachmentVertices; } set { attachmentVertices = value; } }
|
||||
public int AttachmentVerticesCount { get { return attachmentVerticesCount; } set { attachmentVerticesCount = value; } }
|
||||
|
||||
public Slot (SlotData data, Bone bone) {
|
||||
if (data == null) throw new ArgumentNullException("data cannot be null.");
|
||||
if (bone == null) throw new ArgumentNullException("bone cannot be null.");
|
||||
this.data = data;
|
||||
this.bone = bone;
|
||||
SetToSetupPose();
|
||||
}
|
||||
|
||||
internal void SetToSetupPose (int slotIndex) {
|
||||
r = data.r;
|
||||
g = data.g;
|
||||
b = data.b;
|
||||
a = data.a;
|
||||
Attachment = data.attachmentName == null ? null : bone.skeleton.GetAttachment(slotIndex, data.attachmentName);
|
||||
}
|
||||
|
||||
public void SetToSetupPose () {
|
||||
SetToSetupPose(bone.skeleton.data.slots.IndexOf(data));
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return data.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
SpineRuntimes/SpineRuntime21/SlotData.cs
Normal file
62
SpineRuntimes/SpineRuntime21/SlotData.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes Software License
|
||||
* Version 2.1
|
||||
*
|
||||
* Copyright (c) 2013, Esoteric Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||
* non-transferable license to install, execute and perform the Spine Runtimes
|
||||
* Software (the "Software") solely for internal use. Without the written
|
||||
* permission of Esoteric Software (typically granted by licensing Spine), you
|
||||
* may not (a) modify, translate, adapt or otherwise create derivative works,
|
||||
* improvements of the Software or develop new applications using the Software
|
||||
* or (b) remove, delete, alter or obscure any trademarks or any copyright,
|
||||
* trademark, patent or other intellectual property or proprietary rights
|
||||
* notices on or in the Software, including any copy thereof. Redistributions
|
||||
* in binary or source form must include this license and terms.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL ESOTERIC SOFTARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
using System;
|
||||
|
||||
namespace SpineRuntime21 {
|
||||
public class SlotData {
|
||||
internal String name;
|
||||
internal BoneData boneData;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
internal String attachmentName;
|
||||
internal bool additiveBlending;
|
||||
|
||||
public String Name { get { return name; } }
|
||||
public BoneData BoneData { get { return boneData; } }
|
||||
public float R { get { return r; } set { r = value; } }
|
||||
public float G { get { return g; } set { g = value; } }
|
||||
public float B { get { return b; } set { b = value; } }
|
||||
public float A { get { return a; } set { a = value; } }
|
||||
/// <summary>May be null.</summary>
|
||||
public String AttachmentName { get { return attachmentName; } set { attachmentName = value; } }
|
||||
public bool AdditiveBlending { get { return additiveBlending; } set { additiveBlending = value; } }
|
||||
|
||||
public SlotData (String name, BoneData boneData) {
|
||||
if (name == null) throw new ArgumentNullException("name cannot be null.");
|
||||
if (boneData == null) throw new ArgumentNullException("boneData cannot be null.");
|
||||
this.name = name;
|
||||
this.boneData = boneData;
|
||||
}
|
||||
|
||||
override public String ToString () {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
SpineRuntimes/SpineRuntime21/SpineRuntime21.csproj
Normal file
13
SpineRuntimes/SpineRuntime21/SpineRuntime21.csproj
Normal file
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>2.1.25</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -152,27 +152,13 @@ namespace SpineRuntime36 {
|
||||
|
||||
Bone parent = this.parent;
|
||||
if (parent == null) { // Root bone.
|
||||
float rotationY = rotation + 90 + shearY;
|
||||
float la = MathUtils.CosDeg(rotation + shearX) * scaleX;
|
||||
float lb = MathUtils.CosDeg(rotationY) * scaleY;
|
||||
float lc = MathUtils.SinDeg(rotation + shearX) * scaleX;
|
||||
float ld = MathUtils.SinDeg(rotationY) * scaleY;
|
||||
if (skeleton.flipX) {
|
||||
x = -x;
|
||||
la = -la;
|
||||
lb = -lb;
|
||||
}
|
||||
if (skeleton.flipY != yDown) {
|
||||
y = -y;
|
||||
lc = -lc;
|
||||
ld = -ld;
|
||||
}
|
||||
a = la;
|
||||
b = lb;
|
||||
c = lc;
|
||||
d = ld;
|
||||
worldX = x + skeleton.x;
|
||||
worldY = y + skeleton.y;
|
||||
float rotationY = rotation + 90 + shearY, sx = skeleton.scaleX, sy = skeleton.scaleY;
|
||||
a = MathUtils.CosDeg(rotation + shearX) * scaleX * sx;
|
||||
b = MathUtils.CosDeg(rotationY) * scaleY * sx;
|
||||
c = MathUtils.SinDeg(rotation + shearX) * scaleX * sy;
|
||||
d = MathUtils.SinDeg(rotationY) * scaleY * sy;
|
||||
worldX = x * sx + skeleton.x;
|
||||
worldY = y * sy + skeleton.y;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,13 +214,16 @@ namespace SpineRuntime36 {
|
||||
case TransformMode.NoScale:
|
||||
case TransformMode.NoScaleOrReflection: {
|
||||
float cos = MathUtils.CosDeg(rotation), sin = MathUtils.SinDeg(rotation);
|
||||
float za = pa * cos + pb * sin;
|
||||
float zc = pc * cos + pd * sin;
|
||||
float za = (pa * cos + pb * sin) / skeleton.scaleX;
|
||||
float zc = (pc * cos + pd * sin) / skeleton.scaleY;
|
||||
float s = (float)Math.Sqrt(za * za + zc * zc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
za *= s;
|
||||
zc *= s;
|
||||
s = (float)Math.Sqrt(za * za + zc * zc);
|
||||
if (data.transformMode == TransformMode.NoScale
|
||||
&& (pa * pd - pb * pc < 0) != (skeleton.scaleX < 0 != skeleton.scaleY < 0)) s = -s;
|
||||
|
||||
float r = MathUtils.PI / 2 + MathUtils.Atan2(zc, za);
|
||||
float zb = MathUtils.Cos(r) * s;
|
||||
float zd = MathUtils.Sin(r) * s;
|
||||
@@ -242,26 +231,18 @@ namespace SpineRuntime36 {
|
||||
float lb = MathUtils.CosDeg(90 + shearY) * scaleY;
|
||||
float lc = MathUtils.SinDeg(shearX) * scaleX;
|
||||
float ld = MathUtils.SinDeg(90 + shearY) * scaleY;
|
||||
if (data.transformMode != TransformMode.NoScaleOrReflection? pa * pd - pb* pc< 0 : skeleton.flipX != skeleton.flipY) {
|
||||
zb = -zb;
|
||||
zd = -zd;
|
||||
}
|
||||
a = za * la + zb * lc;
|
||||
b = za * lb + zb * ld;
|
||||
c = zc * la + zd * lc;
|
||||
d = zc * lb + zd * ld;
|
||||
return;
|
||||
d = zc * lb + zd * ld;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skeleton.flipX) {
|
||||
a = -a;
|
||||
b = -b;
|
||||
}
|
||||
if (skeleton.flipY != Bone.yDown) {
|
||||
c = -c;
|
||||
d = -d;
|
||||
}
|
||||
a *= skeleton.scaleX;
|
||||
b *= skeleton.scaleX;
|
||||
c *= skeleton.scaleY;
|
||||
d *= skeleton.scaleY;
|
||||
}
|
||||
|
||||
public void SetToSetupPose () {
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace SpineRuntime36 {
|
||||
internal Skin skin;
|
||||
internal float r = 1, g = 1, b = 1, a = 1;
|
||||
internal float time;
|
||||
internal bool flipX, flipY;
|
||||
internal float x, y;
|
||||
internal float scaleX = 1, scaleY = 1;
|
||||
internal float x, y;
|
||||
|
||||
public SkeletonData Data { get { return data; } }
|
||||
public ExposedList<Bone> Bones { get { return bones; } }
|
||||
@@ -64,10 +64,16 @@ namespace SpineRuntime36 {
|
||||
public float Time { get { return time; } set { time = value; } }
|
||||
public float X { get { return x; } set { x = value; } }
|
||||
public float Y { get { return y; } set { y = value; } }
|
||||
public bool FlipX { get { return flipX; } set { flipX = value; } }
|
||||
public bool FlipY { get { return flipY; } set { flipY = value; } }
|
||||
public float ScaleX { get { return scaleX; } set { scaleX = value; } }
|
||||
public float ScaleY { get { return scaleY; } set { scaleY = value; } }
|
||||
|
||||
public Bone RootBone {
|
||||
[Obsolete("Use ScaleX instead. FlipX is when ScaleX is negative.")]
|
||||
public bool FlipX { get { return scaleX < 0; } set { scaleX = value ? -1f : 1f; } }
|
||||
|
||||
[Obsolete("Use ScaleY instead. FlipY is when ScaleY is negative.")]
|
||||
public bool FlipY { get { return scaleY < 0; } set { scaleY = value ? -1f : 1f; } }
|
||||
|
||||
public Bone RootBone {
|
||||
get { return bones.Count == 0 ? null : bones.Items[0]; }
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.6.53</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.7.94</Version>
|
||||
|
||||
@@ -129,8 +129,8 @@ namespace SpineRuntime38 {
|
||||
if (skeletonData.hash.Length == 0) skeletonData.hash = null;
|
||||
skeletonData.version = input.ReadString();
|
||||
if (skeletonData.version.Length == 0) skeletonData.version = null;
|
||||
if ("3.8.75" == skeletonData.version)
|
||||
throw new Exception("Unsupported skeleton data, please export with a newer version of Spine.");
|
||||
//if ("3.8.75" == skeletonData.version)
|
||||
// throw new Exception("Unsupported skeleton data, please export with a newer version of Spine.");
|
||||
skeletonData.x = input.ReadFloat();
|
||||
skeletonData.y = input.ReadFloat();
|
||||
skeletonData.width = input.ReadFloat();
|
||||
|
||||
@@ -100,8 +100,8 @@ namespace SpineRuntime38 {
|
||||
var skeletonMap = (Dictionary<string, Object>)root["skeleton"];
|
||||
skeletonData.hash = (string)skeletonMap["hash"];
|
||||
skeletonData.version = (string)skeletonMap["spine"];
|
||||
if ("3.8.75" == skeletonData.version)
|
||||
throw new Exception("Unsupported skeleton data, please export with a newer version of Spine.");
|
||||
//if ("3.8.75" == skeletonData.version)
|
||||
// throw new Exception("Unsupported skeleton data, please export with a newer version of Spine.");
|
||||
skeletonData.x = GetFloat(skeletonMap, "x", 0);
|
||||
skeletonData.y = GetFloat(skeletonMap, "y", 0);
|
||||
skeletonData.width = GetFloat(skeletonMap, "width", 0);
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>3.8.99</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.0.64</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.1.54</Version>
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<Platforms>x64</Platforms>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BaseOutputPath>$(SolutionDir)out</BaseOutputPath>
|
||||
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
|
||||
<Version>4.2.74</Version>
|
||||
|
||||
@@ -15,6 +15,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
.gitignore = .gitignore
|
||||
CHANGELOG.md = CHANGELOG.md
|
||||
README.en.md = README.en.md
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
@@ -26,6 +28,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpineRuntime41", "SpineRunt
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpineRuntime42", "SpineRuntimes\SpineRuntime42\SpineRuntime42.csproj", "{1D96AAF6-AB7B-8050-4C7E-03431778628F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpineRuntime21", "SpineRuntimes\SpineRuntime21\SpineRuntime21.csproj", "{628CA98E-1D21-2282-C01E-0470CAF211E1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -60,6 +64,10 @@ Global
|
||||
{1D96AAF6-AB7B-8050-4C7E-03431778628F}.Debug|x64.Build.0 = Debug|x64
|
||||
{1D96AAF6-AB7B-8050-4C7E-03431778628F}.Release|x64.ActiveCfg = Release|x64
|
||||
{1D96AAF6-AB7B-8050-4C7E-03431778628F}.Release|x64.Build.0 = Release|x64
|
||||
{628CA98E-1D21-2282-C01E-0470CAF211E1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{628CA98E-1D21-2282-C01E-0470CAF211E1}.Debug|x64.Build.0 = Debug|x64
|
||||
{628CA98E-1D21-2282-C01E-0470CAF211E1}.Release|x64.ActiveCfg = Release|x64
|
||||
{628CA98E-1D21-2282-C01E-0470CAF211E1}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -71,6 +79,7 @@ Global
|
||||
{2E19353C-9C0B-85F7-4EF4-98A778A79059} = {EA2E1399-02BC-43BC-AD9F-42E23E9C3DA8}
|
||||
{C7B93D57-A896-38B2-1D43-25B28502F756} = {EA2E1399-02BC-43BC-AD9F-42E23E9C3DA8}
|
||||
{1D96AAF6-AB7B-8050-4C7E-03431778628F} = {EA2E1399-02BC-43BC-AD9F-42E23E9C3DA8}
|
||||
{628CA98E-1D21-2282-C01E-0470CAF211E1} = {EA2E1399-02BC-43BC-AD9F-42E23E9C3DA8}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {91F0EFD1-4B07-4C3C-82D8-90432349D3A5}
|
||||
|
||||
6
SpineViewer/App.config
Normal file
6
SpineViewer/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="localize" value="zh-CN"/>
|
||||
</appSettings>
|
||||
</configuration>
|
||||
160
SpineViewer/Controls/SkelFileListBox.Designer.cs
generated
Normal file
160
SpineViewer/Controls/SkelFileListBox.Designer.cs
generated
Normal file
@@ -0,0 +1,160 @@
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
partial class SkelFileListBox
|
||||
{
|
||||
/// <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(SkelFileListBox));
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
flowLayoutPanel1 = new FlowLayoutPanel();
|
||||
button_AddFolder = new Button();
|
||||
button_AddFile = new Button();
|
||||
label_Tip = new Label();
|
||||
listBox = new ListBox();
|
||||
contextMenuStrip = new ContextMenuStrip(components);
|
||||
toolStripMenuItem_SelectAll = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Paste = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Remove = new ToolStripMenuItem();
|
||||
folderBrowserDialog = new FolderBrowserDialog();
|
||||
openFileDialog_Skel = new OpenFileDialog();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
flowLayoutPanel1.SuspendLayout();
|
||||
contextMenuStrip.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(flowLayoutPanel1, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(listBox, 0, 1);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// flowLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1");
|
||||
flowLayoutPanel1.Controls.Add(button_AddFolder);
|
||||
flowLayoutPanel1.Controls.Add(button_AddFile);
|
||||
flowLayoutPanel1.Controls.Add(label_Tip);
|
||||
flowLayoutPanel1.Name = "flowLayoutPanel1";
|
||||
//
|
||||
// button_AddFolder
|
||||
//
|
||||
resources.ApplyResources(button_AddFolder, "button_AddFolder");
|
||||
button_AddFolder.Name = "button_AddFolder";
|
||||
button_AddFolder.UseVisualStyleBackColor = true;
|
||||
button_AddFolder.Click += button_AddFolder_Click;
|
||||
//
|
||||
// button_AddFile
|
||||
//
|
||||
resources.ApplyResources(button_AddFile, "button_AddFile");
|
||||
button_AddFile.Name = "button_AddFile";
|
||||
button_AddFile.UseVisualStyleBackColor = true;
|
||||
button_AddFile.Click += button_AddFile_Click;
|
||||
//
|
||||
// label_Tip
|
||||
//
|
||||
resources.ApplyResources(label_Tip, "label_Tip");
|
||||
label_Tip.Name = "label_Tip";
|
||||
//
|
||||
// listBox
|
||||
//
|
||||
resources.ApplyResources(listBox, "listBox");
|
||||
listBox.AllowDrop = true;
|
||||
listBox.ContextMenuStrip = contextMenuStrip;
|
||||
listBox.FormattingEnabled = true;
|
||||
listBox.Name = "listBox";
|
||||
listBox.SelectionMode = SelectionMode.MultiExtended;
|
||||
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";
|
||||
//
|
||||
// toolStripMenuItem_SelectAll
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_SelectAll, "toolStripMenuItem_SelectAll");
|
||||
toolStripMenuItem_SelectAll.Name = "toolStripMenuItem_SelectAll";
|
||||
toolStripMenuItem_SelectAll.Click += toolStripMenuItem_SelectAll_Click;
|
||||
//
|
||||
// toolStripMenuItem_Paste
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Paste, "toolStripMenuItem_Paste");
|
||||
toolStripMenuItem_Paste.Name = "toolStripMenuItem_Paste";
|
||||
toolStripMenuItem_Paste.Click += toolStripMenuItem_Paste_Click;
|
||||
//
|
||||
// toolStripMenuItem_Remove
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_Remove, "toolStripMenuItem_Remove");
|
||||
toolStripMenuItem_Remove.Name = "toolStripMenuItem_Remove";
|
||||
toolStripMenuItem_Remove.Click += toolStripMenuItem_Remove_Click;
|
||||
//
|
||||
// folderBrowserDialog
|
||||
//
|
||||
resources.ApplyResources(folderBrowserDialog, "folderBrowserDialog");
|
||||
//
|
||||
// openFileDialog_Skel
|
||||
//
|
||||
openFileDialog_Skel.AddExtension = false;
|
||||
openFileDialog_Skel.AddToRecent = false;
|
||||
resources.ApplyResources(openFileDialog_Skel, "openFileDialog_Skel");
|
||||
openFileDialog_Skel.Multiselect = true;
|
||||
//
|
||||
// SkelFileListBox
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(tableLayoutPanel1);
|
||||
Name = "SkelFileListBox";
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
flowLayoutPanel1.ResumeLayout(false);
|
||||
flowLayoutPanel1.PerformLayout();
|
||||
contextMenuStrip.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private ListBox listBox;
|
||||
private FlowLayoutPanel flowLayoutPanel1;
|
||||
private Button button_AddFolder;
|
||||
private Button button_AddFile;
|
||||
private FolderBrowserDialog folderBrowserDialog;
|
||||
private Label label_Tip;
|
||||
private ContextMenuStrip contextMenuStrip;
|
||||
private OpenFileDialog openFileDialog_Skel;
|
||||
private ToolStripMenuItem toolStripMenuItem_SelectAll;
|
||||
private ToolStripMenuItem toolStripMenuItem_Paste;
|
||||
private ToolStripMenuItem toolStripMenuItem_Remove;
|
||||
}
|
||||
}
|
||||
125
SpineViewer/Controls/SkelFileListBox.cs
Normal file
125
SpineViewer/Controls/SkelFileListBox.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
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.IO;
|
||||
using SpineViewer.Spine;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
public partial class SkelFileListBox : UserControl
|
||||
{
|
||||
public SkelFileListBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ListBox.Items
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public ListBox.ObjectCollection Items { get => listBox.Items; }
|
||||
|
||||
/// <summary>
|
||||
/// 从路径列表添加
|
||||
/// </summary>
|
||||
private void AddFromFileDrop(string[] paths)
|
||||
{
|
||||
foreach (var path in paths)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
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 (SpineUtils.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
listBox.Items.Add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button_AddFolder_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (folderBrowserDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var path = folderBrowserDialog.SelectedPath;
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
foreach (var file in Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (SpineUtils.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
listBox.Items.Add(file);
|
||||
}
|
||||
}
|
||||
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
|
||||
private void button_AddFile_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (openFileDialog_Skel.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
foreach (var p in openFileDialog_Skel.FileNames)
|
||||
listBox.Items.Add(Path.GetFullPath(p));
|
||||
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
|
||||
private void listBox_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
e.Effect = DragDropEffects.Copy;
|
||||
else
|
||||
e.Effect = DragDropEffects.None;
|
||||
}
|
||||
|
||||
private void listBox_DragDrop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (!e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
return;
|
||||
|
||||
AddFromFileDrop((string[])e.Data.GetData(DataFormats.FileDrop));
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_SelectAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
for (int i = 0; i < listBox.Items.Count; i++)
|
||||
listBox.SelectedIndices.Add(i);
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Paste_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!Clipboard.ContainsFileDropList())
|
||||
return;
|
||||
|
||||
var fileDropList = Clipboard.GetFileDropList();
|
||||
var paths = new string[fileDropList.Count];
|
||||
fileDropList.CopyTo(paths, 0);
|
||||
AddFromFileDrop(paths);
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Remove_Click(object sender, EventArgs e)
|
||||
{
|
||||
var indices = new int[listBox.SelectedIndices.Count];
|
||||
listBox.SelectedIndices.CopyTo(indices, 0);
|
||||
for (int i = indices.Length - 1; i >= 0; i--)
|
||||
listBox.Items.RemoveAt(indices[i]);
|
||||
label_Tip.Text = $"{Properties.Resources.itemCountPrefix}{listBox.Items.Count}{Properties.Resources.itemCountSuffix}";
|
||||
}
|
||||
}
|
||||
}
|
||||
219
SpineViewer/Controls/SkelFileListBox.en.resx
Normal file
219
SpineViewer/Controls/SkelFileListBox.en.resx
Normal file
@@ -0,0 +1,219 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 2</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="flowLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>796, 38</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>224, 94</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="listBox.ItemHeight" type="System.Int32, mscorlib">
|
||||
<value>24</value>
|
||||
</data>
|
||||
<data name="listBox.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 44</value>
|
||||
</data>
|
||||
<data name="listBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="listBox.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>796, 348</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>802, 394</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>129, 34</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Text" xml:space="preserve">
|
||||
<value>Add Folder...</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>138, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>112, 34</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Text" xml:space="preserve">
|
||||
<value>Add Files...</value>
|
||||
</data>
|
||||
<data name="label_Tip.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>256, 7</value>
|
||||
</data>
|
||||
<data name="label_Tip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>117, 24</value>
|
||||
</data>
|
||||
<data name="label_Tip.Text" xml:space="preserve">
|
||||
<value>0 file added.</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>223, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Text" xml:space="preserve">
|
||||
<value>Select all</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>223, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.Text" xml:space="preserve">
|
||||
<value>Paste</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>223, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
|
||||
<value>Remove</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Filter" xml:space="preserve">
|
||||
<value>All files (*.*)|*.*|Skel files (*.skel; *.json)|*.skel;*.json</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Title" xml:space="preserve">
|
||||
<value>Select .skel files</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>11, 24</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>802, 394</value>
|
||||
</data>
|
||||
</root>
|
||||
424
SpineViewer/Controls/SkelFileListBox.resx
Normal file
424
SpineViewer/Controls/SkelFileListBox.resx
Normal file
@@ -0,0 +1,424 @@
|
||||
<?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="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Filter" xml:space="preserve">
|
||||
<value>所有文件 (*.*)|*.*|skel 文件 (*.skel; *.json)|*.skel;*.json</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="button_AddFolder.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>104, 30</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="listBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Name" xml:space="preserve">
|
||||
<value>label_Tip</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="button_AddFile.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>button_AddFile.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="toolStripMenuItem_Remove.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Del</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>button_AddFolder.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="listBox.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="listBox.HorizontalScrollbar" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_SelectAll.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_SelectAll</value>
|
||||
</data>
|
||||
<data name=">>listBox.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 2</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Text" xml:space="preserve">
|
||||
<value>添加文件...</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_SelectAll.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label_Tip.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>202, 7</value>
|
||||
</data>
|
||||
<data name=">>button_AddFolder.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>161, 24</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>110, 2</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+A</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Paste.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Paste</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_AddFolder.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>162, 76</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>listBox.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label_Tip.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleCenter</value>
|
||||
</data>
|
||||
<data name="label_Tip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>115, 20</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Text" xml:space="preserve">
|
||||
<value>全选</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>folderBrowserDialog.Name" xml:space="preserve">
|
||||
<value>folderBrowserDialog</value>
|
||||
</data>
|
||||
<data name="label_Tip.Text" xml:space="preserve">
|
||||
<value>已添加 0 个文件</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="listBox.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>579, 286</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+V</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Remove.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>listBox.Name" xml:space="preserve">
|
||||
<value>listBox</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="listBox.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>listBox.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ListBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Paste.Text" xml:space="preserve">
|
||||
<value>粘贴</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>583, 328</value>
|
||||
</data>
|
||||
<data name="button_AddFile.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>88, 30</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>button_AddFile.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Title" xml:space="preserve">
|
||||
<value>批量选择skel文件</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>button_AddFile.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_AddFile.Name" xml:space="preserve">
|
||||
<value>button_AddFile</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
|
||||
<value>移除</value>
|
||||
</data>
|
||||
<data name="button_AddFile.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Paste.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button_AddFolder.Name" xml:space="preserve">
|
||||
<value>button_AddFolder</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Skel.Name" xml:space="preserve">
|
||||
<value>openFileDialog_Skel</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Text" xml:space="preserve">
|
||||
<value>添加文件夹...</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="label_Tip.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>583, 328</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>SkelFileListBox</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="listBox.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 40</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_AddFolder.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 2</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip.Name" xml:space="preserve">
|
||||
<value>contextMenuStrip</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>579, 34</value>
|
||||
</data>
|
||||
<data name="label_Tip.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Skel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Remove.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Remove</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>161, 24</value>
|
||||
</data>
|
||||
<data name="label_Tip.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name="button_AddFile.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>161, 24</value>
|
||||
</data>
|
||||
<data name=">>folderBrowserDialog.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.FolderBrowserDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label_Tip.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="flowLayoutPanel1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="listBox" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,Percent,100" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<metadata name="folderBrowserDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>286, 21</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>556, 18</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog_Skel.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>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>
|
||||
226
SpineViewer/Controls/SpineListView.Designer.cs
generated
226
SpineViewer/Controls/SpineListView.Designer.cs
generated
@@ -29,6 +29,7 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpineListView));
|
||||
listView = new ListView();
|
||||
columnHeader_Name = new ColumnHeader();
|
||||
contextMenuStrip = new ContextMenuStrip(components);
|
||||
@@ -36,118 +37,230 @@
|
||||
toolStripMenuItem_Insert = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Remove = new ToolStripMenuItem();
|
||||
toolStripSeparator1 = new ToolStripSeparator();
|
||||
toolStripMenuItem_MoveUp = new ToolStripMenuItem();
|
||||
toolStripMenuItem_MoveDown = new ToolStripMenuItem();
|
||||
toolStripSeparator2 = new ToolStripSeparator();
|
||||
toolStripMenuItem_BatchAdd = new ToolStripMenuItem();
|
||||
toolStripMenuItem_RemoveAll = new ToolStripMenuItem();
|
||||
toolStripSeparator2 = new ToolStripSeparator();
|
||||
toolStripMenuItem_MoveUp = new ToolStripMenuItem();
|
||||
toolStripMenuItem_MoveDown = new ToolStripMenuItem();
|
||||
toolStripMenuItem_MoveTop = new ToolStripMenuItem();
|
||||
toolStripMenuItem_MoveBottom = new ToolStripMenuItem();
|
||||
toolStripSeparator3 = new ToolStripSeparator();
|
||||
toolStripMenuItem_CopyPreview = new ToolStripMenuItem();
|
||||
toolStripMenuItem_AddFromClipboard = new ToolStripMenuItem();
|
||||
toolStripMenuItem_SelectAll = new ToolStripMenuItem();
|
||||
toolStripSeparator4 = new ToolStripSeparator();
|
||||
toolStripMenuItem_ChangeView = new ToolStripMenuItem();
|
||||
toolStripMenuItem_LargeIconView = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ListView = new ToolStripMenuItem();
|
||||
toolStripMenuItem_DetailsView = new ToolStripMenuItem();
|
||||
imageList_LargeIcon = new ImageList(components);
|
||||
imageList_SmallIcon = new ImageList(components);
|
||||
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
|
||||
//
|
||||
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.Location = new Point(0, 0);
|
||||
listView.LargeImageList = imageList_LargeIcon;
|
||||
listView.Name = "listView";
|
||||
listView.ShowItemToolTips = true;
|
||||
listView.Size = new Size(336, 445);
|
||||
listView.TabIndex = 1;
|
||||
listView.SmallImageList = imageList_SmallIcon;
|
||||
listView.UseCompatibleStateImageBehavior = false;
|
||||
listView.View = View.Details;
|
||||
listView.ItemDrag += listView_ItemDrag;
|
||||
listView.SelectedIndexChanged += listView_SelectedIndexChanged;
|
||||
listView.DragDrop += listView_DragDrop;
|
||||
listView.DragEnter += listView_DragEnter;
|
||||
listView.DragOver += listView_DragOver;
|
||||
listView.KeyDown += listView_KeyDown;
|
||||
//
|
||||
// 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_MoveUp, toolStripMenuItem_MoveDown, toolStripSeparator2, toolStripMenuItem_BatchAdd, toolStripMenuItem_RemoveAll });
|
||||
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(188, 226);
|
||||
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(187, 30);
|
||||
toolStripMenuItem_Add.Text = "添加(&A)...";
|
||||
toolStripMenuItem_Add.Click += toolStripMenuItem_Add_Click;
|
||||
//
|
||||
// toolStripMenuItem_Insert
|
||||
//
|
||||
toolStripMenuItem_Insert.Enabled = false;
|
||||
resources.ApplyResources(toolStripMenuItem_Insert, "toolStripMenuItem_Insert");
|
||||
toolStripMenuItem_Insert.Name = "toolStripMenuItem_Insert";
|
||||
toolStripMenuItem_Insert.Size = new Size(187, 30);
|
||||
toolStripMenuItem_Insert.Text = "插入(&I)...";
|
||||
toolStripMenuItem_Insert.Click += toolStripMenuItem_Insert_Click;
|
||||
//
|
||||
// toolStripMenuItem_Remove
|
||||
//
|
||||
toolStripMenuItem_Remove.Enabled = false;
|
||||
resources.ApplyResources(toolStripMenuItem_Remove, "toolStripMenuItem_Remove");
|
||||
toolStripMenuItem_Remove.Name = "toolStripMenuItem_Remove";
|
||||
toolStripMenuItem_Remove.Size = new Size(187, 30);
|
||||
toolStripMenuItem_Remove.Text = "移除(&R)";
|
||||
toolStripMenuItem_Remove.Click += toolStripMenuItem_Remove_Click;
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1");
|
||||
toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
toolStripSeparator1.Size = new Size(184, 6);
|
||||
//
|
||||
// toolStripMenuItem_MoveUp
|
||||
//
|
||||
toolStripMenuItem_MoveUp.Name = "toolStripMenuItem_MoveUp";
|
||||
toolStripMenuItem_MoveUp.Size = new Size(187, 30);
|
||||
toolStripMenuItem_MoveUp.Text = "上移(&U)";
|
||||
toolStripMenuItem_MoveUp.Click += toolStripMenuItem_MoveUp_Click;
|
||||
//
|
||||
// toolStripMenuItem_MoveDown
|
||||
//
|
||||
toolStripMenuItem_MoveDown.Name = "toolStripMenuItem_MoveDown";
|
||||
toolStripMenuItem_MoveDown.Size = new Size(187, 30);
|
||||
toolStripMenuItem_MoveDown.Text = "下移(&D)";
|
||||
toolStripMenuItem_MoveDown.Click += toolStripMenuItem_MoveDown_Click;
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
toolStripSeparator2.Size = new Size(184, 6);
|
||||
//
|
||||
// toolStripMenuItem_BatchAdd
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_BatchAdd, "toolStripMenuItem_BatchAdd");
|
||||
toolStripMenuItem_BatchAdd.Name = "toolStripMenuItem_BatchAdd";
|
||||
toolStripMenuItem_BatchAdd.Size = new Size(187, 30);
|
||||
toolStripMenuItem_BatchAdd.Text = "批量添加(&B)...";
|
||||
toolStripMenuItem_BatchAdd.Click += toolStripMenuItem_BatchAdd_Click;
|
||||
//
|
||||
// toolStripMenuItem_RemoveAll
|
||||
//
|
||||
toolStripMenuItem_RemoveAll.Enabled = false;
|
||||
resources.ApplyResources(toolStripMenuItem_RemoveAll, "toolStripMenuItem_RemoveAll");
|
||||
toolStripMenuItem_RemoveAll.Name = "toolStripMenuItem_RemoveAll";
|
||||
toolStripMenuItem_RemoveAll.Size = new Size(187, 30);
|
||||
toolStripMenuItem_RemoveAll.Text = "移除全部(&X)";
|
||||
toolStripMenuItem_RemoveAll.Click += toolStripMenuItem_RemoveAll_Click;
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2");
|
||||
toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
//
|
||||
// toolStripMenuItem_MoveUp
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_MoveUp, "toolStripMenuItem_MoveUp");
|
||||
toolStripMenuItem_MoveUp.Name = "toolStripMenuItem_MoveUp";
|
||||
toolStripMenuItem_MoveUp.Click += toolStripMenuItem_MoveUp_Click;
|
||||
//
|
||||
// toolStripMenuItem_MoveDown
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_MoveDown, "toolStripMenuItem_MoveDown");
|
||||
toolStripMenuItem_MoveDown.Name = "toolStripMenuItem_MoveDown";
|
||||
toolStripMenuItem_MoveDown.Click += toolStripMenuItem_MoveDown_Click;
|
||||
//
|
||||
// toolStripMenuItem_MoveTop
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_MoveTop, "toolStripMenuItem_MoveTop");
|
||||
toolStripMenuItem_MoveTop.Name = "toolStripMenuItem_MoveTop";
|
||||
toolStripMenuItem_MoveTop.Click += toolStripMenuItem_MoveTop_Click;
|
||||
//
|
||||
// toolStripMenuItem_MoveBottom
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_MoveBottom, "toolStripMenuItem_MoveBottom");
|
||||
toolStripMenuItem_MoveBottom.Name = "toolStripMenuItem_MoveBottom";
|
||||
toolStripMenuItem_MoveBottom.Click += toolStripMenuItem_MoveBottom_Click;
|
||||
//
|
||||
// toolStripSeparator3
|
||||
//
|
||||
resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3");
|
||||
toolStripSeparator3.Name = "toolStripSeparator3";
|
||||
//
|
||||
// toolStripMenuItem_CopyPreview
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_CopyPreview, "toolStripMenuItem_CopyPreview");
|
||||
toolStripMenuItem_CopyPreview.Name = "toolStripMenuItem_CopyPreview";
|
||||
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";
|
||||
//
|
||||
// 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_LargeIconView
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_LargeIconView, "toolStripMenuItem_LargeIconView");
|
||||
toolStripMenuItem_LargeIconView.Name = "toolStripMenuItem_LargeIconView";
|
||||
toolStripMenuItem_LargeIconView.Click += toolStripMenuItem_LargeIconView_Click;
|
||||
//
|
||||
// toolStripMenuItem_ListView
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ListView, "toolStripMenuItem_ListView");
|
||||
toolStripMenuItem_ListView.Name = "toolStripMenuItem_ListView";
|
||||
toolStripMenuItem_ListView.Click += toolStripMenuItem_ListView_Click;
|
||||
//
|
||||
// toolStripMenuItem_DetailsView
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_DetailsView, "toolStripMenuItem_DetailsView");
|
||||
toolStripMenuItem_DetailsView.Name = "toolStripMenuItem_DetailsView";
|
||||
toolStripMenuItem_DetailsView.Click += toolStripMenuItem_DetailsView_Click;
|
||||
//
|
||||
// imageList_LargeIcon
|
||||
//
|
||||
imageList_LargeIcon.ColorDepth = ColorDepth.Depth32Bit;
|
||||
resources.ApplyResources(imageList_LargeIcon, "imageList_LargeIcon");
|
||||
imageList_LargeIcon.TransparentColor = Color.Transparent;
|
||||
//
|
||||
// imageList_SmallIcon
|
||||
//
|
||||
imageList_SmallIcon.ColorDepth = ColorDepth.Depth32Bit;
|
||||
resources.ApplyResources(imageList_SmallIcon, "imageList_SmallIcon");
|
||||
imageList_SmallIcon.TransparentColor = Color.Transparent;
|
||||
//
|
||||
// timer_SelectedIndexChangedDebounce
|
||||
//
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -164,5 +277,22 @@
|
||||
private ToolStripMenuItem toolStripMenuItem_MoveDown;
|
||||
private ToolStripSeparator toolStripSeparator2;
|
||||
private ColumnHeader columnHeader_Name;
|
||||
private ImageList imageList_SmallIcon;
|
||||
private ImageList imageList_LargeIcon;
|
||||
private ToolStripSeparator toolStripSeparator3;
|
||||
private ToolStripMenuItem toolStripMenuItem_ChangeView;
|
||||
private ToolStripMenuItem toolStripMenuItem_LargeIconView;
|
||||
private ToolStripMenuItem toolStripMenuItem_ListView;
|
||||
private ToolStripMenuItem toolStripMenuItem_DetailsView;
|
||||
private ToolStripMenuItem toolStripMenuItem_MoveTop;
|
||||
private ToolStripMenuItem toolStripMenuItem_MoveBottom;
|
||||
private ToolStripMenuItem toolStripMenuItem_CopyPreview;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,23 +11,36 @@ using System.Collections.ObjectModel;
|
||||
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
|
||||
{
|
||||
[Category("自定义"), Description("用于显示骨骼属性的属性页")]
|
||||
public PropertyGrid? PropertyGrid { get; set; }
|
||||
/// <summary>
|
||||
/// 日志器
|
||||
/// </summary>
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 获取数组快照, 访问时必须使用 lock 语句锁定对象本身
|
||||
/// Spine 列表只读视图, 访问时必须使用 lock 语句锁定视图本身
|
||||
/// </summary>
|
||||
public readonly ReadOnlyCollection<Spine.Spine> Spines;
|
||||
public readonly ReadOnlyCollection<SpineObject> Spines;
|
||||
|
||||
/// <summary>
|
||||
/// Spine 列表, 访问时必须使用 lock 语句锁定 Spines
|
||||
/// 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()
|
||||
{
|
||||
@@ -35,18 +48,41 @@ 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>
|
||||
public ListView.SelectedIndexCollection SelectedIndices => listView.SelectedIndices;
|
||||
|
||||
/// <summary>
|
||||
/// 弹出添加对话框在末尾添加
|
||||
/// </summary>
|
||||
public void Add() => Insert();
|
||||
|
||||
/// <summary>
|
||||
/// 弹出添加对话框在指定位置之前插入一项, 如果索引无效则在末尾添加
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从结果在指定位置之前插入一项, 如果索引无效则在末尾添加
|
||||
/// </summary>
|
||||
private void Insert(Dialogs.OpenSpineDialogResult result, int index = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
var spine = Spine.Spine.New(dialog.Version, dialog.SkelPath, dialog.AtlasPath);
|
||||
var spine = SpineObject.New(result.Version, result.SkelPath, result.AtlasPath);
|
||||
|
||||
// 如果索引无效则在末尾添加
|
||||
if (index < 0 || index > listView.Items.Count)
|
||||
@@ -54,7 +90,10 @@ namespace SpineViewer.Controls
|
||||
|
||||
// 锁定外部的读操作
|
||||
lock (Spines) { spines.Insert(index, spine); }
|
||||
listView.Items.Insert(index, new ListViewItem(spine.Name) { ToolTipText = spine.SkelPath });
|
||||
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 });
|
||||
|
||||
// 选中新增项
|
||||
listView.SelectedIndices.Clear();
|
||||
@@ -62,20 +101,12 @@ namespace SpineViewer.Controls
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Logger.Error(ex.ToString());
|
||||
Program.Logger.Error("Failed to load {} {}", dialog.SkelPath, dialog.AtlasPath);
|
||||
MessageBox.Show(ex.ToString(), "骨骼加载失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
logger.Error(ex.ToString());
|
||||
logger.Error("Failed to load {} {}", result.SkelPath, result.AtlasPath);
|
||||
MessagePopup.Error(ex.ToString(), Properties.Resources.errorLoadSkeleton);
|
||||
}
|
||||
|
||||
Program.Logger.Info($"Current memory usage: {Program.Process.WorkingSet64 / 1024.0 / 1024.0:F2} MB");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 弹出添加对话框
|
||||
/// </summary>
|
||||
public void Add()
|
||||
{
|
||||
Insert();
|
||||
logger.LogCurrentProcessMemoryUsage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -84,19 +115,28 @@ 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>
|
||||
private void BatchAdd(Dialogs.BatchOpenSpineDialogResult result)
|
||||
{
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += BatchAdd_Work;
|
||||
progressDialog.RunWorkerAsync(openDialog);
|
||||
progressDialog.RunWorkerAsync(result);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量添加后台任务
|
||||
/// </summary>
|
||||
private void BatchAdd_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = sender as BackgroundWorker;
|
||||
var arguments = e.Argument as Dialogs.BatchOpenSpineDialog;
|
||||
var arguments = e.Argument as Dialogs.BatchOpenSpineDialogResult;
|
||||
var skelPaths = arguments.SkelPaths;
|
||||
var version = arguments.Version;
|
||||
|
||||
@@ -104,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)
|
||||
@@ -117,60 +157,128 @@ 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); }
|
||||
listView.Invoke(() => listView.Items.Add(new ListViewItem(spine.Name) { ToolTipText = spine.SkelPath }));
|
||||
spinePropertyWrappers[spine.ID] = new(spine);
|
||||
listView.Invoke(() =>
|
||||
{
|
||||
listView.SmallImageList.Images.Add(spine.ID, preview);
|
||||
listView.LargeImageList.Images.Add(spine.ID, preview);
|
||||
listView.Items.Add(new ListViewItem(spine.Name, spine.ID) { ToolTipText = spine.SkelPath });
|
||||
});
|
||||
success++;
|
||||
}
|
||||
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
|
||||
logger.Info("{} skel loaded successfully", success);
|
||||
|
||||
logger.LogCurrentProcessMemoryUsage();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从拖放/复制的路径列表添加
|
||||
/// </summary>
|
||||
private void AddFromFileDrop(IEnumerable<string> paths)
|
||||
{
|
||||
List<string> validPaths = [];
|
||||
foreach (var path in paths)
|
||||
{
|
||||
Program.Logger.Info("{} skel loaded successfully", success);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
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 (SpineUtils.CommonSkelSuffix.Contains(Path.GetExtension(file).ToLower()))
|
||||
validPaths.Add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Program.Logger.Info($"Current memory usage: {Program.Process.WorkingSet64 / 1024.0 / 1024.0:F2} MB");
|
||||
if (validPaths.Count > 1)
|
||||
{
|
||||
if (validPaths.Count > 100)
|
||||
{
|
||||
if (MessagePopup.Quest($"{Properties.Resources.loadAllSkeletonPrefix}{validPaths.Count}{Properties.Resources.loadAllSkeletonSuffix}", Properties.Resources.msgBoxQuest) == DialogResult.Cancel)
|
||||
return;
|
||||
}
|
||||
BatchAdd(new Dialogs.BatchOpenSpineDialogResult(SpineVersion.Auto, validPaths.ToArray()));
|
||||
}
|
||||
else if (validPaths.Count > 0)
|
||||
{
|
||||
Insert(new Dialogs.OpenSpineDialogResult(SpineVersion.Auto, validPaths[0]));
|
||||
}
|
||||
}
|
||||
|
||||
private void listView_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (PropertyGrid is not null)
|
||||
{
|
||||
lock (Spines)
|
||||
{
|
||||
if (listView.SelectedIndices.Count <= 0)
|
||||
PropertyGrid.SelectedObject = null;
|
||||
else if (listView.SelectedIndices.Count <= 1)
|
||||
PropertyGrid.SelectedObject = spines[listView.SelectedIndices[0]];
|
||||
else
|
||||
PropertyGrid.SelectedObjects = listView.SelectedIndices.Cast<int>().Select(index => spines[index]).ToArray();
|
||||
}
|
||||
}
|
||||
timer_SelectedIndexChangedDebounce.Stop();
|
||||
timer_SelectedIndexChangedDebounce.Start();
|
||||
}
|
||||
|
||||
private void listView_KeyDown(object sender, KeyEventArgs e)
|
||||
private void timer_SelectedIndexChangedDebounce_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if (e.Control && e.KeyCode == Keys.A)
|
||||
timer_SelectedIndexChangedDebounce.Stop();
|
||||
_listView_SelectedIndexChanged(listView, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void _listView_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
lock (Spines)
|
||||
{
|
||||
if (SpinePropertyGrid is not null)
|
||||
{
|
||||
if (listView.SelectedIndices.Count <= 0)
|
||||
SpinePropertyGrid.SelectedSpines = null;
|
||||
else if (listView.SelectedIndices.Count <= 1)
|
||||
SpinePropertyGrid.SelectedSpines = [spinePropertyWrappers[spines[listView.SelectedIndices[0]].ID]];
|
||||
else
|
||||
SpinePropertyGrid.SelectedSpines = listView.SelectedIndices.Cast<int>().Select(index => spinePropertyWrappers[spines[index].ID]).ToArray();
|
||||
}
|
||||
|
||||
// 标记选中的 Spine
|
||||
for (int i = 0; i < spines.Count; i++)
|
||||
spines[i].IsSelected = listView.SelectedIndices.Contains(i);
|
||||
}
|
||||
|
||||
// XXX: 图标显示的时候没法自动刷新顺序, 只能切换视图刷新, 不知道什么原理
|
||||
if (listView.View == View.LargeIcon)
|
||||
{
|
||||
listView.BeginUpdate();
|
||||
foreach (ListViewItem item in listView.Items)
|
||||
{
|
||||
item.Selected = true;
|
||||
}
|
||||
listView.View = View.List;
|
||||
listView.View = View.LargeIcon;
|
||||
listView.EndUpdate();
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -178,74 +286,108 @@ namespace SpineViewer.Controls
|
||||
DoDragDrop(e.Item, DragDropEffects.Move);
|
||||
}
|
||||
|
||||
private void listView_DragEnter(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.Serializable))
|
||||
e.Effect = DragDropEffects.Move;
|
||||
else if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
e.Effect = DragDropEffects.Copy;
|
||||
else
|
||||
e.Effect = DragDropEffects.None;
|
||||
}
|
||||
|
||||
private void listView_DragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
// 检查拖放目标是否有效
|
||||
e.Effect = DragDropEffects.Move;
|
||||
|
||||
// 获取鼠标位置并确定目标索引
|
||||
var point = listView.PointToClient(new(e.X, e.Y));
|
||||
var targetItem = listView.GetItemAt(point.X, point.Y);
|
||||
|
||||
// 高亮目标项
|
||||
if (targetItem != null)
|
||||
if (e.Data.GetDataPresent(DataFormats.Serializable))
|
||||
{
|
||||
foreach (ListViewItem item in listView.Items)
|
||||
// 获取鼠标位置并确定目标索引
|
||||
var point = listView.PointToClient(new(e.X, e.Y));
|
||||
var targetItem = listView.GetItemAt(point.X, point.Y);
|
||||
|
||||
// 高亮目标项
|
||||
if (targetItem != null)
|
||||
{
|
||||
item.BackColor = listView.BackColor;
|
||||
foreach (ListViewItem item in listView.Items)
|
||||
{
|
||||
item.BackColor = listView.BackColor;
|
||||
}
|
||||
targetItem.BackColor = Color.LightGray;
|
||||
}
|
||||
targetItem.BackColor = Color.LightGray;
|
||||
}
|
||||
}
|
||||
|
||||
private void listView_DragDrop(object sender, DragEventArgs e)
|
||||
{
|
||||
// 获取拖放源项和目标项
|
||||
var draggedItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
|
||||
int draggedIndex = draggedItem.Index;
|
||||
var point = listView.PointToClient(new Point(e.X, e.Y));
|
||||
var targetItem = listView.GetItemAt(point.X, point.Y);
|
||||
int targetIndex = targetItem is null ? listView.Items.Count : targetItem.Index;
|
||||
if (e.Data.GetDataPresent(DataFormats.Serializable))
|
||||
{
|
||||
// 获取拖放源项和目标项
|
||||
var draggedItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
|
||||
int draggedIndex = draggedItem.Index;
|
||||
var point = listView.PointToClient(new Point(e.X, e.Y));
|
||||
var targetItem = listView.GetItemAt(point.X, point.Y);
|
||||
int targetIndex = targetItem is null ? listView.Items.Count : targetItem.Index;
|
||||
|
||||
if (targetIndex <= draggedIndex)
|
||||
{
|
||||
lock (Spines)
|
||||
if (targetIndex <= draggedIndex)
|
||||
{
|
||||
var draggedSpine = spines[draggedIndex];
|
||||
spines.RemoveAt(draggedIndex);
|
||||
spines.Insert(targetIndex, draggedSpine);
|
||||
lock (Spines)
|
||||
{
|
||||
var draggedSpine = spines[draggedIndex];
|
||||
spines.RemoveAt(draggedIndex);
|
||||
spines.Insert(targetIndex, draggedSpine);
|
||||
}
|
||||
listView.Items.RemoveAt(draggedIndex);
|
||||
listView.Items.Insert(targetIndex, draggedItem);
|
||||
}
|
||||
listView.Items.RemoveAt(draggedIndex);
|
||||
listView.Items.Insert(targetIndex, draggedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (Spines)
|
||||
else
|
||||
{
|
||||
var draggedSpine = spines[draggedIndex];
|
||||
spines.RemoveAt(draggedIndex);
|
||||
spines.Insert(targetIndex - 1, draggedSpine);
|
||||
lock (Spines)
|
||||
{
|
||||
var draggedSpine = spines[draggedIndex];
|
||||
spines.RemoveAt(draggedIndex);
|
||||
spines.Insert(targetIndex - 1, draggedSpine);
|
||||
}
|
||||
listView.Items.RemoveAt(draggedIndex);
|
||||
listView.Items.Insert(targetIndex - 1, draggedItem);
|
||||
}
|
||||
listView.Items.RemoveAt(draggedIndex);
|
||||
listView.Items.Insert(targetIndex - 1, draggedItem);
|
||||
}
|
||||
|
||||
// 重置背景颜色
|
||||
foreach (ListViewItem item in listView.Items)
|
||||
// 重置背景颜色
|
||||
foreach (ListViewItem item in listView.Items)
|
||||
{
|
||||
item.BackColor = listView.BackColor;
|
||||
}
|
||||
}
|
||||
else if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
{
|
||||
item.BackColor = listView.BackColor;
|
||||
AddFromFileDrop((string[])e.Data.GetData(DataFormats.FileDrop));
|
||||
}
|
||||
}
|
||||
|
||||
private void contextMenuStrip_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
var selectedCount = listView.SelectedIndices.Count;
|
||||
var selectedIndices = listView.SelectedIndices;
|
||||
var selectedCount = selectedIndices.Count;
|
||||
var itemsCount = listView.Items.Count;
|
||||
toolStripMenuItem_Insert.Enabled = selectedCount == 1;
|
||||
toolStripMenuItem_Remove.Enabled = selectedCount >= 1;
|
||||
toolStripMenuItem_MoveUp.Enabled = selectedCount == 1 && listView.SelectedIndices[0] != 0;
|
||||
toolStripMenuItem_MoveDown.Enabled = selectedCount == 1 && listView.SelectedIndices[0] != itemsCount - 1;
|
||||
toolStripMenuItem_MoveTop.Enabled = selectedCount == 1 && selectedIndices[0] != 0;
|
||||
toolStripMenuItem_MoveUp.Enabled = selectedCount == 1 && selectedIndices[0] != 0;
|
||||
toolStripMenuItem_MoveDown.Enabled = selectedCount == 1 && selectedIndices[0] != itemsCount - 1;
|
||||
toolStripMenuItem_MoveBottom.Enabled = selectedCount == 1 && selectedIndices[0] != itemsCount - 1;
|
||||
toolStripMenuItem_RemoveAll.Enabled = itemsCount > 0;
|
||||
toolStripMenuItem_CopyPreview.Enabled = selectedCount > 0;
|
||||
|
||||
// 视图选项
|
||||
toolStripMenuItem_LargeIconView.Checked = listView.View == View.LargeIcon;
|
||||
toolStripMenuItem_ListView.Checked = listView.View == View.List;
|
||||
toolStripMenuItem_DetailsView.Checked = listView.View == View.Details;
|
||||
}
|
||||
|
||||
private void contextMenuStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e)
|
||||
{
|
||||
// 不显示菜单的时候需要把菜单的各项功能启用, 这样才能正常捕获快捷键
|
||||
foreach (var item in contextMenuStrip.Items)
|
||||
if (item is ToolStripMenuItem tsmi)
|
||||
tsmi.Enabled = true;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Add_Click(object sender, EventArgs e)
|
||||
@@ -271,18 +413,44 @@ namespace SpineViewer.Controls
|
||||
|
||||
if (listView.SelectedIndices.Count > 1)
|
||||
{
|
||||
if (MessageBox.Show($"确定移除所选 {listView.SelectedIndices.Count} 项吗?", "操作确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != 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.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();
|
||||
}
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_MoveTop_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listView.SelectedIndices.Count != 1)
|
||||
return;
|
||||
|
||||
var index = listView.SelectedIndices[0];
|
||||
if (index > 0)
|
||||
{
|
||||
lock (Spines)
|
||||
{
|
||||
spines[i].Dispose();
|
||||
spines.RemoveAt(i);
|
||||
var spine = spines[index];
|
||||
spines.RemoveAt(index);
|
||||
spines.Insert(0, spine);
|
||||
}
|
||||
listView.Items.RemoveAt(i);
|
||||
var item = listView.Items[index];
|
||||
listView.Items.RemoveAt(index);
|
||||
listView.Items.Insert(0, item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,8 +464,10 @@ namespace SpineViewer.Controls
|
||||
{
|
||||
lock (Spines) { (spines[index - 1], spines[index]) = (spines[index], spines[index - 1]); }
|
||||
var item = listView.Items[index];
|
||||
listView.BeginUpdate();
|
||||
listView.Items.RemoveAt(index);
|
||||
listView.Items.Insert(index - 1, item);
|
||||
listView.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,9 +480,31 @@ namespace SpineViewer.Controls
|
||||
if (index < listView.Items.Count - 1)
|
||||
{
|
||||
lock (Spines) { (spines[index], spines[index + 1]) = (spines[index + 1], spines[index]); }
|
||||
var item = listView.Items[index + 1];
|
||||
listView.Items.RemoveAt(index + 1);
|
||||
listView.Items.Insert(index, item);
|
||||
var item = listView.Items[index];
|
||||
listView.BeginUpdate();
|
||||
listView.Items.RemoveAt(index);
|
||||
listView.Items.Insert(index + 1, item);
|
||||
listView.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_MoveBottom_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listView.SelectedIndices.Count != 1)
|
||||
return;
|
||||
|
||||
var index = listView.SelectedIndices[0];
|
||||
if (index < listView.Items.Count - 1)
|
||||
{
|
||||
lock (Spines)
|
||||
{
|
||||
var spine = spines[index];
|
||||
spines.RemoveAt(index);
|
||||
spines.Add(spine);
|
||||
}
|
||||
var item = listView.Items[index];
|
||||
listView.Items.RemoveAt(index);
|
||||
listView.Items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,18 +513,80 @@ namespace SpineViewer.Controls
|
||||
if (listView.Items.Count <= 0)
|
||||
return;
|
||||
|
||||
if (MessageBox.Show($"确认移除所有 {listView.Items.Count} 项吗?", "操作确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
|
||||
if (MessagePopup.Quest($"{Properties.Resources.removeAllItemPrefix} {listView.Items.Count} {Properties.Resources.removeItemConfirmSuffix}", Properties.Resources.msgBoxQuest) != DialogResult.OK)
|
||||
return;
|
||||
|
||||
lock (Spines)
|
||||
{
|
||||
foreach (var spine in spines)
|
||||
spine.Dispose();
|
||||
spines.Clear();
|
||||
}
|
||||
listView.Items.Clear();
|
||||
if (PropertyGrid is not null)
|
||||
PropertyGrid.SelectedObject = null;
|
||||
lock (Spines)
|
||||
{
|
||||
foreach (var spine in spines) spine.Dispose();
|
||||
spines.Clear();
|
||||
spinePropertyWrappers.Clear();
|
||||
listView.SmallImageList.Images.Clear();
|
||||
listView.LargeImageList.Images.Clear();
|
||||
}
|
||||
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(tempDir, $"{spine.ID}.png");
|
||||
spine.Preview.Save(path);
|
||||
fileDropList.Add(path);
|
||||
}
|
||||
}
|
||||
if (fileDropList.Count > 0)
|
||||
Clipboard.SetFileDropList(fileDropList);
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_AddFromClipboard_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (Clipboard.ContainsFileDropList())
|
||||
{
|
||||
var fileDropList = Clipboard.GetFileDropList();
|
||||
var paths = new string[fileDropList.Count];
|
||||
fileDropList.CopyTo(paths, 0);
|
||||
AddFromFileDrop(paths);
|
||||
}
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_SelectAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
listView.BeginUpdate();
|
||||
foreach (ListViewItem item in listView.Items)
|
||||
item.Selected = true;
|
||||
listView.EndUpdate();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_LargeIconView_Click(object sender, EventArgs e)
|
||||
{
|
||||
listView.View = View.LargeIcon;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ListView_Click(object sender, EventArgs e)
|
||||
{
|
||||
listView.View = View.List;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_DetailsView_Click(object sender, EventArgs e)
|
||||
{
|
||||
listView.View = View.Details;
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultSpineConfig
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
241
SpineViewer/Controls/SpineListView.en.resx
Normal file
241
SpineViewer/Controls/SpineListView.en.resx
Normal file
@@ -0,0 +1,241 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="columnHeader_Name.Text" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>298, 418</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Add.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Add.Text" xml:space="preserve">
|
||||
<value>Add to...</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Insert.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Insert.Text" xml:space="preserve">
|
||||
<value>Insert...</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
|
||||
<value>Remove</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>294, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchAdd.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchAdd.Text" xml:space="preserve">
|
||||
<value>Bulk add...</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAll.Text" xml:space="preserve">
|
||||
<value>Remove all</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>294, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.Text" xml:space="preserve">
|
||||
<value>Up</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.Text" xml:space="preserve">
|
||||
<value>Down</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.Text" xml:space="preserve">
|
||||
<value>Stick to top</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.Text" xml:space="preserve">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>294, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.Text" xml:space="preserve">
|
||||
<value>Copy preview</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddFromClipboard.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddFromClipboard.Text" xml:space="preserve">
|
||||
<value>Add to clipboard</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Text" xml:space="preserve">
|
||||
<value>Select all</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>294, 6</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ChangeView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>297, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ChangeView.Text" xml:space="preserve">
|
||||
<value>Switch view</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>258, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.Text" xml:space="preserve">
|
||||
<value>Large icon</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ListView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>258, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ListView.Text" xml:space="preserve">
|
||||
<value>List</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>258, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.Text" xml:space="preserve">
|
||||
<value>Details</value>
|
||||
</data>
|
||||
<data name="toolStripStatusLabel_CountInfo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>266, 24</value>
|
||||
</data>
|
||||
<data name="toolStripStatusLabel_CountInfo.Text" xml:space="preserve">
|
||||
<value>0 items selected, 0 items total</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,7 +117,452 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name=">>imageList_LargeIcon.Name" xml:space="preserve">
|
||||
<value>imageList_LargeIcon</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="toolStripMenuItem_AddFromClipboard.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveDown.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>imageList_SmallIcon.Name" xml:space="preserve">
|
||||
<value>imageList_SmallIcon</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>251, 6</value>
|
||||
</data>
|
||||
<data name="toolStripStatusLabel_CountInfo.Text" xml:space="preserve">
|
||||
<value>已选择 0 项,共 0 项</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Insert.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Insert</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Add.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_DetailsView.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_DetailsView</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>241, 34</value>
|
||||
</data>
|
||||
<data name=">>imageList_SmallIcon.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>251, 6</value>
|
||||
</data>
|
||||
<data name="statusStrip.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 414</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_AddFromClipboard.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>336, 445</value>
|
||||
</data>
|
||||
<data name="statusStrip.Text" xml:space="preserve">
|
||||
<value>statusStrip1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="columnHeader_Name.Text" xml:space="preserve">
|
||||
<value>名称</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator2.Name" xml:space="preserve">
|
||||
<value>toolStripSeparator2</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveTop.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.Text" xml:space="preserve">
|
||||
<value>置底</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_BatchAdd.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_BatchAdd</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name=">>columnHeader_Name.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAll.Text" xml:space="preserve">
|
||||
<value>移除全部</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Add.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>listView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ListView, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>statusStrip.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Remove.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Remove</value>
|
||||
</data>
|
||||
<data name=">>statusStrip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.StatusStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Remove.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>251, 6</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>SpineListView</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveUp.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="toolStripMenuItem_ListView.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+2</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_LargeIconView.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_LargeIconView</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="listView" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="statusStrip" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>timer_SelectedIndexChangedDebounce.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Timer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>listView.Name" xml:space="preserve">
|
||||
<value>listView</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.Text" xml:space="preserve">
|
||||
<value>上移</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Insert.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.Text" xml:space="preserve">
|
||||
<value>详细信息</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveTop.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_MoveTop</value>
|
||||
</data>
|
||||
<data name="statusStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>336, 31</value>
|
||||
</data>
|
||||
<data name="toolStripSeparator2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>251, 6</value>
|
||||
</data>
|
||||
<data name=">>statusStrip.Name" xml:space="preserve">
|
||||
<value>statusStrip</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveBottom.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+Shift+S</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator4.Name" xml:space="preserve">
|
||||
<value>toolStripSeparator4</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddFromClipboard.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+V</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveBottom.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchAdd.Text" xml:space="preserve">
|
||||
<value>批量添加...</value>
|
||||
</data>
|
||||
<data name=">>imageList_LargeIcon.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ChangeView.Text" xml:space="preserve">
|
||||
<value>切换视图</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ListView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>listView.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveBottom.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_MoveBottom</value>
|
||||
</data>
|
||||
<data name="listView.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_AddFromClipboard.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_AddFromClipboard</value>
|
||||
</data>
|
||||
<data name="columnHeader_Name.Width" type="System.Int32, mscorlib">
|
||||
<value>300</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator1.Name" xml:space="preserve">
|
||||
<value>toolStripSeparator1</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.Text" xml:space="preserve">
|
||||
<value>移除</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_BatchAdd.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_RemoveAll.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_RemoveAll</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.Text" xml:space="preserve">
|
||||
<value>置顶</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_DetailsView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ListView.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_ListView</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ListView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>241, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+S</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripStatusLabel_CountInfo.Name" xml:space="preserve">
|
||||
<value>toolStripStatusLabel_CountInfo</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>listView.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>statusStrip.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel</value>
|
||||
</data>
|
||||
<data name="listView.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_CopyPreview.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveUp.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_MoveUp</value>
|
||||
</data>
|
||||
<data name="listView.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Insert.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Remove.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Del</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveUp.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+W</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ChangeView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name=">>timer_SelectedIndexChangedDebounce.Name" xml:space="preserve">
|
||||
<value>timer_SelectedIndexChangedDebounce</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+C</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_SelectAll.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_SelectAll</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator3.Name" xml:space="preserve">
|
||||
<value>toolStripSeparator3</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_Add.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_Add</value>
|
||||
</data>
|
||||
<data name="listView.Alignment" type="System.Windows.Forms.ListViewAlignment, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ListView.Text" xml:space="preserve">
|
||||
<value>列表</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddFromClipboard.Text" xml:space="preserve">
|
||||
<value>从剪贴板添加</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_LargeIconView.Text" xml:space="preserve">
|
||||
<value>大图标</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.RowCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+3</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.Text" xml:space="preserve">
|
||||
<value>全选</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_BatchAdd.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>255, 418</value>
|
||||
</data>
|
||||
<data name="statusStrip.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_LargeIconView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripStatusLabel_CountInfo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>178, 24</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveDown.Text" xml:space="preserve">
|
||||
<value>下移</value>
|
||||
</data>
|
||||
<data name="imageList_SmallIcon.ImageSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>48, 48</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ChangeView.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_ChangeView</value>
|
||||
</data>
|
||||
<data name=">>columnHeader_Name.Name" xml:space="preserve">
|
||||
<value>columnHeader_Name</value>
|
||||
</data>
|
||||
<data name="listView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>336, 414</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_CopyPreview.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_CopyPreview</value>
|
||||
</data>
|
||||
<data name="imageList_LargeIcon.ImageSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>96, 96</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_RemoveAll.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="listView.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip.Name" xml:space="preserve">
|
||||
<value>contextMenuStrip</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_MoveDown.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_MoveDown</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_SelectAll.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Ctrl+A</value>
|
||||
</data>
|
||||
<data name=">>toolStripSeparator4.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="statusStrip.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_DetailsView.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>241, 34</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>254, 30</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_CopyPreview.Text" xml:space="preserve">
|
||||
<value>复制预览图</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>11, 24</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_MoveTop.ShortcutKeys" type="System.Windows.Forms.Keys, System.Windows.Forms">
|
||||
<value>Alt+Shift+W</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Insert.Text" xml:space="preserve">
|
||||
<value>插入...</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ChangeView.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_SelectAll.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripStatusLabel_CountInfo.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_Add.Text" xml:space="preserve">
|
||||
<value>添加...</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>336, 445</value>
|
||||
</data>
|
||||
<metadata name="timer_SelectedIndexChangedDebounce.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>771, 24</value>
|
||||
</metadata>
|
||||
<metadata name="statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>1176, 24</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
<value>30, 22</value>
|
||||
</metadata>
|
||||
<metadata name="imageList_LargeIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>511, 20</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="imageList_SmallIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>252, 19</value>
|
||||
</metadata>
|
||||
</root>
|
||||
231
SpineViewer/Controls/SpinePreviewPanel.Designer.cs
generated
Normal file
231
SpineViewer/Controls/SpinePreviewPanel.Designer.cs
generated
Normal file
@@ -0,0 +1,231 @@
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
partial class SpinePreviewPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 组件设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpinePreviewPanel));
|
||||
panel_Render = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
flowLayoutPanel1 = new FlowLayoutPanel();
|
||||
button_Stop = new Button();
|
||||
imageList = new ImageList(components);
|
||||
button_Restart = new Button();
|
||||
button_Start = new Button();
|
||||
button_ForwardStep = new Button();
|
||||
button_ForwardFast = new Button();
|
||||
button_FullScreen = new Button();
|
||||
panel_ViewContainer = new Panel();
|
||||
panel_RenderContainer = new Panel();
|
||||
toolTip = new ToolTip(components);
|
||||
spinePreviewFullScreenForm = new SpineViewer.Forms.SpinePreviewFullScreenForm();
|
||||
wallpaperForm = new WallpaperForm();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
flowLayoutPanel1.SuspendLayout();
|
||||
panel_ViewContainer.SuspendLayout();
|
||||
panel_RenderContainer.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel_Render
|
||||
//
|
||||
resources.ApplyResources(panel_Render, "panel_Render");
|
||||
panel_Render.BackColor = SystemColors.ControlDarkDark;
|
||||
panel_Render.Name = "panel_Render";
|
||||
toolTip.SetToolTip(panel_Render, resources.GetString("panel_Render.ToolTip"));
|
||||
panel_Render.MouseDown += panel_Render_MouseDown;
|
||||
panel_Render.MouseMove += panel_Render_MouseMove;
|
||||
panel_Render.MouseUp += panel_Render_MouseUp;
|
||||
panel_Render.MouseWheel += panel_Render_MouseWheel;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(flowLayoutPanel1, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(panel_ViewContainer, 0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
toolTip.SetToolTip(tableLayoutPanel1, resources.GetString("tableLayoutPanel1.ToolTip"));
|
||||
//
|
||||
// flowLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(flowLayoutPanel1, "flowLayoutPanel1");
|
||||
flowLayoutPanel1.Controls.Add(button_Stop);
|
||||
flowLayoutPanel1.Controls.Add(button_Restart);
|
||||
flowLayoutPanel1.Controls.Add(button_Start);
|
||||
flowLayoutPanel1.Controls.Add(button_ForwardStep);
|
||||
flowLayoutPanel1.Controls.Add(button_ForwardFast);
|
||||
flowLayoutPanel1.Controls.Add(button_FullScreen);
|
||||
flowLayoutPanel1.Name = "flowLayoutPanel1";
|
||||
toolTip.SetToolTip(flowLayoutPanel1, resources.GetString("flowLayoutPanel1.ToolTip"));
|
||||
//
|
||||
// button_Stop
|
||||
//
|
||||
resources.ApplyResources(button_Stop, "button_Stop");
|
||||
button_Stop.ImageList = imageList;
|
||||
button_Stop.Name = "button_Stop";
|
||||
toolTip.SetToolTip(button_Stop, resources.GetString("button_Stop.ToolTip"));
|
||||
button_Stop.UseVisualStyleBackColor = true;
|
||||
button_Stop.Click += button_Stop_Click;
|
||||
//
|
||||
// imageList
|
||||
//
|
||||
imageList.ColorDepth = ColorDepth.Depth32Bit;
|
||||
imageList.ImageStream = (ImageListStreamer)resources.GetObject("imageList.ImageStream");
|
||||
imageList.TransparentColor = Color.Transparent;
|
||||
imageList.Images.SetKeyName(0, "arrows-maximize");
|
||||
imageList.Images.SetKeyName(1, "forward-fast");
|
||||
imageList.Images.SetKeyName(2, "forward-step");
|
||||
imageList.Images.SetKeyName(3, "pause");
|
||||
imageList.Images.SetKeyName(4, "rotate-left");
|
||||
imageList.Images.SetKeyName(5, "start");
|
||||
imageList.Images.SetKeyName(6, "stop");
|
||||
//
|
||||
// button_Restart
|
||||
//
|
||||
resources.ApplyResources(button_Restart, "button_Restart");
|
||||
button_Restart.ImageList = imageList;
|
||||
button_Restart.Name = "button_Restart";
|
||||
toolTip.SetToolTip(button_Restart, resources.GetString("button_Restart.ToolTip"));
|
||||
button_Restart.UseVisualStyleBackColor = true;
|
||||
button_Restart.Click += button_Restart_Click;
|
||||
//
|
||||
// button_Start
|
||||
//
|
||||
resources.ApplyResources(button_Start, "button_Start");
|
||||
button_Start.ImageList = imageList;
|
||||
button_Start.Name = "button_Start";
|
||||
toolTip.SetToolTip(button_Start, resources.GetString("button_Start.ToolTip"));
|
||||
button_Start.UseVisualStyleBackColor = true;
|
||||
button_Start.Click += button_Start_Click;
|
||||
//
|
||||
// button_ForwardStep
|
||||
//
|
||||
resources.ApplyResources(button_ForwardStep, "button_ForwardStep");
|
||||
button_ForwardStep.ImageList = imageList;
|
||||
button_ForwardStep.Name = "button_ForwardStep";
|
||||
toolTip.SetToolTip(button_ForwardStep, resources.GetString("button_ForwardStep.ToolTip"));
|
||||
button_ForwardStep.UseVisualStyleBackColor = true;
|
||||
button_ForwardStep.Click += button_ForwardStep_Click;
|
||||
//
|
||||
// button_ForwardFast
|
||||
//
|
||||
resources.ApplyResources(button_ForwardFast, "button_ForwardFast");
|
||||
button_ForwardFast.ImageList = imageList;
|
||||
button_ForwardFast.Name = "button_ForwardFast";
|
||||
toolTip.SetToolTip(button_ForwardFast, resources.GetString("button_ForwardFast.ToolTip"));
|
||||
button_ForwardFast.UseVisualStyleBackColor = true;
|
||||
button_ForwardFast.Click += button_ForwardFast_Click;
|
||||
//
|
||||
// button_FullScreen
|
||||
//
|
||||
resources.ApplyResources(button_FullScreen, "button_FullScreen");
|
||||
button_FullScreen.ImageList = imageList;
|
||||
button_FullScreen.Name = "button_FullScreen";
|
||||
toolTip.SetToolTip(button_FullScreen, resources.GetString("button_FullScreen.ToolTip"));
|
||||
button_FullScreen.UseVisualStyleBackColor = true;
|
||||
button_FullScreen.Click += button_FullScreen_Click;
|
||||
//
|
||||
// panel_ViewContainer
|
||||
//
|
||||
resources.ApplyResources(panel_ViewContainer, "panel_ViewContainer");
|
||||
panel_ViewContainer.Controls.Add(panel_RenderContainer);
|
||||
panel_ViewContainer.Name = "panel_ViewContainer";
|
||||
toolTip.SetToolTip(panel_ViewContainer, resources.GetString("panel_ViewContainer.ToolTip"));
|
||||
//
|
||||
// panel_RenderContainer
|
||||
//
|
||||
resources.ApplyResources(panel_RenderContainer, "panel_RenderContainer");
|
||||
panel_RenderContainer.BackColor = SystemColors.ControlDark;
|
||||
panel_RenderContainer.Controls.Add(panel_Render);
|
||||
panel_RenderContainer.Name = "panel_RenderContainer";
|
||||
toolTip.SetToolTip(panel_RenderContainer, resources.GetString("panel_RenderContainer.ToolTip"));
|
||||
panel_RenderContainer.SizeChanged += panel_RenderContainer_SizeChanged;
|
||||
//
|
||||
// spinePreviewFullScreenForm
|
||||
//
|
||||
resources.ApplyResources(spinePreviewFullScreenForm, "spinePreviewFullScreenForm");
|
||||
spinePreviewFullScreenForm.ControlBox = false;
|
||||
spinePreviewFullScreenForm.FormBorderStyle = FormBorderStyle.None;
|
||||
spinePreviewFullScreenForm.MaximizeBox = false;
|
||||
spinePreviewFullScreenForm.MinimizeBox = false;
|
||||
spinePreviewFullScreenForm.Name = "SpinePreviewFullScreenForm";
|
||||
spinePreviewFullScreenForm.ShowIcon = false;
|
||||
spinePreviewFullScreenForm.ShowInTaskbar = false;
|
||||
toolTip.SetToolTip(spinePreviewFullScreenForm, resources.GetString("spinePreviewFullScreenForm.ToolTip"));
|
||||
spinePreviewFullScreenForm.TopMost = true;
|
||||
spinePreviewFullScreenForm.FormClosing += spinePreviewFullScreenForm_FormClosing;
|
||||
spinePreviewFullScreenForm.KeyDown += spinePreviewFullScreenForm_KeyDown;
|
||||
//
|
||||
// wallpaperForm
|
||||
//
|
||||
resources.ApplyResources(wallpaperForm, "wallpaperForm");
|
||||
wallpaperForm.ControlBox = false;
|
||||
wallpaperForm.FormBorderStyle = FormBorderStyle.None;
|
||||
wallpaperForm.MaximizeBox = false;
|
||||
wallpaperForm.MinimizeBox = false;
|
||||
wallpaperForm.Name = "WallpaperForm";
|
||||
wallpaperForm.ShowIcon = false;
|
||||
wallpaperForm.ShowInTaskbar = false;
|
||||
toolTip.SetToolTip(wallpaperForm, resources.GetString("wallpaperForm.ToolTip"));
|
||||
wallpaperForm.WindowState = FormWindowState.Minimized;
|
||||
wallpaperForm.FormClosing += wallpaperForm_FormClosing;
|
||||
//
|
||||
// SpinePreviewPanel
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(tableLayoutPanel1);
|
||||
Name = "SpinePreviewPanel";
|
||||
toolTip.SetToolTip(this, resources.GetString("$this.ToolTip"));
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
flowLayoutPanel1.ResumeLayout(false);
|
||||
flowLayoutPanel1.PerformLayout();
|
||||
panel_ViewContainer.ResumeLayout(false);
|
||||
panel_RenderContainer.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel_Render;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Panel panel_RenderContainer;
|
||||
private FlowLayoutPanel flowLayoutPanel1;
|
||||
private Button button_Stop;
|
||||
private Button button_Start;
|
||||
private ImageList imageList;
|
||||
private ToolTip toolTip;
|
||||
private Button button_ForwardStep;
|
||||
private Button button_ForwardFast;
|
||||
private Button button_Restart;
|
||||
private Button button_FullScreen;
|
||||
private Panel panel_ViewContainer;
|
||||
private Forms.SpinePreviewFullScreenForm spinePreviewFullScreenForm;
|
||||
private WallpaperForm wallpaperForm;
|
||||
}
|
||||
}
|
||||
837
SpineViewer/Controls/SpinePreviewPanel.cs
Normal file
837
SpineViewer/Controls/SpinePreviewPanel.cs
Normal file
@@ -0,0 +1,837 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Security.Policy;
|
||||
using System.Diagnostics;
|
||||
using NLog;
|
||||
using SpineViewer.Utils;
|
||||
using System.Drawing.Design;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using SpineViewer.Utils.Localize;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
public partial class SpinePreviewPanel : UserControl
|
||||
{
|
||||
public SpinePreviewPanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 日志器
|
||||
/// </summary>
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 要绑定的 Spine 列表控件
|
||||
/// </summary>
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDescription(typeof(Properties.Resources), "descAssociatedSpineListView")]
|
||||
public SpineListView? SpineListView { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 属性信息面板
|
||||
/// </summary>
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDescription(typeof(Properties.Resources), "descDisplayImageProperties")]
|
||||
public PropertyGrid? PropertyGrid
|
||||
{
|
||||
get => propertyGrid;
|
||||
set
|
||||
{
|
||||
propertyGrid = value;
|
||||
if (propertyGrid is not null)
|
||||
propertyGrid.SelectedObject = new SpinePreviewPanelProperty(this);
|
||||
}
|
||||
}
|
||||
private PropertyGrid? propertyGrid;
|
||||
|
||||
#region 参数属性
|
||||
|
||||
/// <summary>
|
||||
/// 分辨率
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public Size Resolution
|
||||
{
|
||||
get => resolution;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
if (value == resolution) return;
|
||||
if (value.Width <= 0) value.Width = 100;
|
||||
if (value.Height <= 0) value.Height = 100;
|
||||
|
||||
var previousZoom = Zoom;
|
||||
|
||||
float parentW = panel_Render.Parent.Width;
|
||||
float parentH = panel_Render.Parent.Height;
|
||||
float renderW = value.Width;
|
||||
float renderH = value.Height;
|
||||
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
||||
renderW *= scale;
|
||||
renderH *= scale;
|
||||
|
||||
panel_Render.Location = new((int)((parentW - renderW) / 2 + 0.5), (int)((parentH - renderH) / 2 + 0.5));
|
||||
panel_Render.Size = new((int)(renderW + 0.5), (int)(renderH + 0.5));
|
||||
resolution = value;
|
||||
|
||||
// 设置完 resolution 后还原缩放比例
|
||||
Zoom = previousZoom;
|
||||
|
||||
// 设置壁纸窗口分辨率
|
||||
using var view = renderWindow.GetView();
|
||||
wallpaperWindow.SetView(view);
|
||||
wallpaperForm.Size = value; // 必须两个 Size 都设置
|
||||
wallpaperWindow.Size = new((uint)value.Width, (uint)value.Height);
|
||||
}
|
||||
}
|
||||
private Size resolution = new(100, 100);
|
||||
|
||||
/// <summary>
|
||||
/// 画面中心点
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public PointF Center
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return new(-1, -1);
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var center = view.Center;
|
||||
return new(center.X, center.Y);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
view.Center = new(value.X, value.Y);
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画面缩放
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public float Zoom
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return -1;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return resolution.Width / Math.Abs(view.Size.X);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
value = Math.Clamp(value, 0.001f, 1000f);
|
||||
using var view = renderWindow.GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
view.Size = new(resolution.Width / value * signX, resolution.Height / value * signY);
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画面旋转
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public float Rotation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return -1;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Rotation;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
view.Rotation = value;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 水平翻转
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool FlipX
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return false;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Size.X < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.X > 0 && value || size.X < 0 && !value)
|
||||
size.X *= -1;
|
||||
view.Size = size;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 垂直翻转
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool FlipY
|
||||
{
|
||||
get
|
||||
{
|
||||
if (renderWindow is null) return false;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
return view.Size.Y < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
using var view = renderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.Y > 0 && value || size.Y < 0 && !value)
|
||||
size.Y *= -1;
|
||||
view.Size = size;
|
||||
renderWindow.SetView(view);
|
||||
wallpaperWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅渲染选中
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool RenderSelectedOnly { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 显示坐标轴
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool ShowAxis { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 最大帧率
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public uint MaxFps
|
||||
{
|
||||
get => maxFps;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
renderWindow.SetFramerateLimit(value);
|
||||
maxFps = value;
|
||||
}
|
||||
}
|
||||
private uint maxFps = 60;
|
||||
|
||||
/// <summary>
|
||||
/// 获取 View
|
||||
/// </summary>
|
||||
public SFML.Graphics.View GetView() => renderWindow.GetView();
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启桌面投影
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool EnableDesktopProjection
|
||||
{
|
||||
get => enableDesktopProjection;
|
||||
set
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
if (enableDesktopProjection == value) return;
|
||||
if (value)
|
||||
{
|
||||
var screenBounds = Screen.FromControl(this).Bounds;
|
||||
Resolution = screenBounds.Size;
|
||||
wallpaperWindow.Position = new(screenBounds.X, screenBounds.Y);
|
||||
wallpaperForm.Show();
|
||||
}
|
||||
else
|
||||
{
|
||||
wallpaperForm.Hide();
|
||||
}
|
||||
enableDesktopProjection = value;
|
||||
}
|
||||
}
|
||||
private bool enableDesktopProjection = false;
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面背景色
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public SFML.Graphics.Color BackgroundColor { get; set; } = new(105, 105, 105);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 渲染管理
|
||||
|
||||
/// <summary>
|
||||
/// 预览画面坐标轴颜色
|
||||
/// </summary>
|
||||
private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220);
|
||||
|
||||
/// <summary>
|
||||
/// 坐标轴顶点缓冲区
|
||||
/// </summary>
|
||||
private readonly SFML.Graphics.VertexArray axisVertices = new(SFML.Graphics.PrimitiveType.Lines, 2); // XXX: 暂时未使用 Dispose 释放
|
||||
|
||||
/// <summary>
|
||||
/// 渲染窗口
|
||||
/// </summary>
|
||||
private SFML.Graphics.RenderWindow renderWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 壁纸窗口
|
||||
/// </summary>
|
||||
private SFML.Graphics.RenderWindow wallpaperWindow;
|
||||
|
||||
/// <summary>
|
||||
/// 帧间隔计时器
|
||||
/// </summary>
|
||||
private readonly SFML.System.Clock clock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 渲染任务
|
||||
/// </summary>
|
||||
private Task? task = null;
|
||||
private CancellationTokenSource? cancelToken = null;
|
||||
|
||||
/// <summary>
|
||||
/// 是否更新画面
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool IsUpdating
|
||||
{
|
||||
get => isUpdating;
|
||||
private set
|
||||
{
|
||||
if (value == isUpdating) return;
|
||||
if (value)
|
||||
{
|
||||
button_Start.ImageKey = "pause";
|
||||
}
|
||||
else
|
||||
{
|
||||
button_Start.ImageKey = "start";
|
||||
}
|
||||
isUpdating = value;
|
||||
}
|
||||
}
|
||||
private bool isUpdating = true;
|
||||
|
||||
/// <summary>
|
||||
/// 快进时间量
|
||||
/// </summary>
|
||||
private float forwardDelta = 0;
|
||||
private object _forwardDeltaLock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 开始渲染
|
||||
/// </summary>
|
||||
public void StartRender()
|
||||
{
|
||||
// 延迟到第一次开启渲染时进行初始化
|
||||
if (renderWindow is null)
|
||||
{
|
||||
renderWindow = new(panel_Render.Handle);
|
||||
renderWindow.SetActive(false);
|
||||
wallpaperWindow = new(wallpaperForm.Handle);
|
||||
wallpaperWindow.SetActive(false);
|
||||
|
||||
// 设置默认参数
|
||||
Resolution = new(2048, 2048);
|
||||
Zoom = 1;
|
||||
Center = new(0, 0);
|
||||
FlipY = true;
|
||||
MaxFps = 30;
|
||||
}
|
||||
|
||||
if (task is not null) return;
|
||||
cancelToken = new();
|
||||
task = Task.Run(RenderTask, cancelToken.Token);
|
||||
IsUpdating = true;
|
||||
if (enableDesktopProjection) wallpaperForm.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止渲染
|
||||
/// </summary>
|
||||
public void StopRender()
|
||||
{
|
||||
if (wallpaperForm.InvokeRequired) wallpaperForm.Invoke(wallpaperForm.Hide);
|
||||
else wallpaperForm.Hide();
|
||||
IsUpdating = false;
|
||||
if (task is null || cancelToken is null)
|
||||
return;
|
||||
cancelToken.Cancel();
|
||||
task.Wait();
|
||||
cancelToken = null;
|
||||
task = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 渲染任务
|
||||
/// </summary>
|
||||
private void RenderTask()
|
||||
{
|
||||
try
|
||||
{
|
||||
renderWindow.SetActive(true);
|
||||
wallpaperWindow.SetActive(true);
|
||||
|
||||
float delta;
|
||||
while (cancelToken is not null && !cancelToken.IsCancellationRequested)
|
||||
{
|
||||
// 必须让 SFML 有机会处理窗口消息, 例如位置和大小变化
|
||||
renderWindow.DispatchEvents();
|
||||
|
||||
delta = clock.ElapsedTime.AsSeconds();
|
||||
clock.Restart();
|
||||
|
||||
// 停止更新的时候只是时间不前进, 但是坐标变换还是要更新, 否则无法移动对象
|
||||
if (!IsUpdating) delta = 0;
|
||||
|
||||
// 加上要快进的量
|
||||
lock (_forwardDeltaLock)
|
||||
{
|
||||
delta += forwardDelta;
|
||||
forwardDelta = 0;
|
||||
}
|
||||
|
||||
renderWindow.Clear(BackgroundColor);
|
||||
if (enableDesktopProjection) wallpaperWindow.Clear(BackgroundColor);
|
||||
|
||||
if (ShowAxis)
|
||||
{
|
||||
// 画一个很长的坐标轴, 用 1e9 比较合适
|
||||
axisVertices[0] = new(new(-1e9f, 0), AxisColor);
|
||||
axisVertices[1] = new(new(1e9f, 0), AxisColor);
|
||||
renderWindow.Draw(axisVertices);
|
||||
axisVertices[0] = new(new(0, -1e9f), AxisColor);
|
||||
axisVertices[1] = new(new(0, 1e9f), AxisColor);
|
||||
renderWindow.Draw(axisVertices);
|
||||
}
|
||||
|
||||
// 渲染 Spine
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines.Where(sp => !sp.IsHidden).ToArray();
|
||||
for (int i = spines.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (cancelToken is not null && cancelToken.IsCancellationRequested)
|
||||
break; // 提前中止
|
||||
|
||||
var spine = spines[i];
|
||||
|
||||
spine.Update(delta);
|
||||
|
||||
if (RenderSelectedOnly && !spine.IsSelected)
|
||||
continue;
|
||||
|
||||
spine.EnableDebug = true;
|
||||
renderWindow.Draw(spine);
|
||||
spine.EnableDebug = false;
|
||||
|
||||
if (enableDesktopProjection) wallpaperWindow.Draw(spine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderWindow.Display();
|
||||
|
||||
if (enableDesktopProjection) wallpaperWindow.Display();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Fatal(ex.ToString());
|
||||
logger.Fatal("Render task stopped");
|
||||
MessagePopup.Error(ex.ToString(), Properties.Resources.previewRenderStopped);
|
||||
}
|
||||
finally
|
||||
{
|
||||
renderWindow.SetActive(false);
|
||||
wallpaperWindow.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 画面拖放对象世界坐标源点
|
||||
/// </summary>
|
||||
private SFML.System.Vector2f? draggingSrc = null;
|
||||
|
||||
private void panel_RenderContainer_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
if (renderWindow is null) return;
|
||||
|
||||
float parentW = panel_Render.Parent.Width;
|
||||
float parentH = panel_Render.Parent.Height;
|
||||
float renderW = panel_Render.Width;
|
||||
float renderH = panel_Render.Height;
|
||||
float scale = Math.Min(parentW / renderW, parentH / renderH); // 两方向取较小值, 保证 parent 覆盖 render
|
||||
renderW *= scale;
|
||||
renderH *= scale;
|
||||
|
||||
panel_Render.Location = new((int)((parentW - renderW) / 2 + 0.5), (int)((parentH - renderH) / 2 + 0.5));
|
||||
panel_Render.Size = new((int)(renderW + 0.5), (int)(renderH + 0.5));
|
||||
}
|
||||
|
||||
private void panel_Render_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
// 右键优先级高, 进入画面拖动模式, 需要重新记录源点
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
draggingSrc = renderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
Cursor = Cursors.Hand;
|
||||
}
|
||||
// 按下了左键并且右键是松开的
|
||||
else if ((e.Button & MouseButtons.Left) != 0 && (MouseButtons & MouseButtons.Right) == 0)
|
||||
{
|
||||
draggingSrc = renderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
var src = new PointF(((SFML.System.Vector2f)draggingSrc).X, ((SFML.System.Vector2f)draggingSrc).Y);
|
||||
|
||||
if (SpineListView is null)
|
||||
return;
|
||||
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines;
|
||||
|
||||
// 仅渲染选中模式禁止在画面里选择对象
|
||||
if (RenderSelectedOnly)
|
||||
{
|
||||
// 只在被选中的对象里判断是否有效命中
|
||||
bool hit = false;
|
||||
foreach (int i in SpineListView.SelectedIndices)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
if (!spines[i].GetCurrentBounds().Contains(src)) continue;
|
||||
hit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果没点到被选中的模型, 则不允许拖动
|
||||
if (!hit) draggingSrc = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ModifierKeys & Keys.Control) == 0)
|
||||
{
|
||||
// 没按 Ctrl 的情况下, 如果命中了已选中对象, 则就算普通命中
|
||||
bool hit = false;
|
||||
for (int i = 0; i < spines.Count; i++)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
if (!spines[i].GetCurrentBounds().Contains(src)) continue;
|
||||
|
||||
hit = true;
|
||||
|
||||
// 如果点到了没被选中的东西, 则清空原先选中的, 改为只选中这一次点的
|
||||
if (!SpineListView.SelectedIndices.Contains(i))
|
||||
{
|
||||
SpineListView.SelectedIndices.Clear();
|
||||
SpineListView.SelectedIndices.Add(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果点了空白的地方, 就清空选中列表
|
||||
if (!hit) SpineListView.SelectedIndices.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 按下 Ctrl 的情况就执行多选, 并且点空白处也不会清空选中
|
||||
for (int i = 0; i < spines.Count; i++)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
if (!spines[i].GetCurrentBounds().Contains(src)) continue;
|
||||
|
||||
SpineListView.SelectedIndices.Add(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_Render_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (renderWindow is null) return;
|
||||
|
||||
if (draggingSrc is null) return;
|
||||
|
||||
var src = (SFML.System.Vector2f)draggingSrc;
|
||||
var dst = renderWindow.MapPixelToCoords(new(e.X, e.Y));
|
||||
var _delta = dst - src;
|
||||
var delta = new SizeF(_delta.X, _delta.Y);
|
||||
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
Center -= delta;
|
||||
}
|
||||
else if ((e.Button & MouseButtons.Left) != 0)
|
||||
{
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines;
|
||||
foreach (int i in SpineListView.SelectedIndices)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
spines[i].Position += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
draggingSrc = dst;
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_Render_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
// 右键高优先级, 结束画面拖动模式
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
SpineListView?.SpinePropertyGrid?.Refresh();
|
||||
|
||||
draggingSrc = null;
|
||||
Cursor = Cursors.Default;
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
// 按下了左键并且右键是松开的
|
||||
else if ((e.Button & MouseButtons.Left) != 0 && (MouseButtons & MouseButtons.Right) == 0)
|
||||
{
|
||||
draggingSrc = null;
|
||||
SpineListView?.SpinePropertyGrid?.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_Render_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
var factor = (e.Delta > 0 ? 1.1f : 0.9f);
|
||||
if ((ModifierKeys & Keys.Control) == 0)
|
||||
{
|
||||
Zoom *= factor;
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
var spines = SpineListView.Spines;
|
||||
foreach (int i in SpineListView.SelectedIndices)
|
||||
{
|
||||
if (spines[i].IsHidden) continue;
|
||||
spines[i].Scale *= factor;
|
||||
}
|
||||
}
|
||||
SpineListView.SpinePropertyGrid?.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button_Stop_Click(object sender, EventArgs e)
|
||||
{
|
||||
IsUpdating = false;
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
foreach (var spine in SpineListView.Spines)
|
||||
spine.ResetAnimationsTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button_Restart_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (SpineListView is not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
foreach (var spine in SpineListView.Spines)
|
||||
spine.ResetAnimationsTime();
|
||||
}
|
||||
}
|
||||
IsUpdating = true;
|
||||
}
|
||||
|
||||
private void button_Start_Click(object sender, EventArgs e)
|
||||
{
|
||||
IsUpdating = !IsUpdating;
|
||||
}
|
||||
|
||||
private void button_ForwardStep_Click(object sender, EventArgs e)
|
||||
{
|
||||
lock (_forwardDeltaLock)
|
||||
{
|
||||
if (maxFps > 0)
|
||||
forwardDelta += 1f / maxFps;
|
||||
else
|
||||
forwardDelta += 0.001f;
|
||||
}
|
||||
}
|
||||
|
||||
private void button_ForwardFast_Click(object sender, EventArgs e)
|
||||
{
|
||||
lock (_forwardDeltaLock)
|
||||
{
|
||||
if (maxFps > 0)
|
||||
forwardDelta += 10f / maxFps;
|
||||
else
|
||||
forwardDelta += 0.01f;
|
||||
}
|
||||
}
|
||||
|
||||
private void button_FullScreen_Click(object sender, EventArgs e)
|
||||
{
|
||||
var screenBounds = Screen.FromControl(this).Bounds;
|
||||
Resolution = screenBounds.Size;
|
||||
PropertyGrid?.Refresh();
|
||||
|
||||
// PerfMonitorV2 模式下, 位置和大小需要分开设置
|
||||
// 因为目标位置的 DPI 可能发生变化, 因此在 WM_POSITIONCHANGED 之后会收到 WM_DPICHANGED
|
||||
// 进而导致一次额外的 WM_SIZE 消息, 其大小是 DPI 修改前的大小, 这个消息在此次设置之后发生
|
||||
// 因此如果同时设置位置和大小则大小可能设置失败
|
||||
spinePreviewFullScreenForm.Location = screenBounds.Location;
|
||||
spinePreviewFullScreenForm.Size = screenBounds.Size;
|
||||
spinePreviewFullScreenForm.Controls.Add(panel_RenderContainer);
|
||||
spinePreviewFullScreenForm.Show();
|
||||
}
|
||||
|
||||
private void spinePreviewFullScreenForm_KeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyCode == Keys.Escape)
|
||||
{
|
||||
spinePreviewFullScreenForm.Hide();
|
||||
panel_ViewContainer.Controls.Add(panel_RenderContainer);
|
||||
}
|
||||
}
|
||||
|
||||
private void spinePreviewFullScreenForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
e.Cancel = e.CloseReason == CloseReason.UserClosing;
|
||||
}
|
||||
|
||||
private void wallpaperForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
e.Cancel = e.CloseReason == CloseReason.UserClosing;
|
||||
}
|
||||
|
||||
//public void ClickStopButton() => button_Stop_Click(button_Stop, EventArgs.Empty);
|
||||
//public void ClickRestartButton() => button_Restart_Click(button_Restart, EventArgs.Empty);
|
||||
//public void ClickStartButton() => button_Start_Click(button_Start, EventArgs.Empty);
|
||||
//public void ClickForwardStepButton() => button_ForwardStep_Click(button_ForwardStep, EventArgs.Empty);
|
||||
//public void ClickForwardFastButton() => button_ForwardFast_Click(button_ForwardFast, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用于在 PropertyGrid 上显示 <see cref="SpinePreviewPanel"/> 属性的包装类, 提供用户操作接口
|
||||
/// </summary>
|
||||
public class SpinePreviewPanelProperty(SpinePreviewPanel previewPanel)
|
||||
{
|
||||
[Browsable(false)]
|
||||
public SpinePreviewPanel PreviewPanel { get; } = previewPanel;
|
||||
|
||||
[RefreshProperties(RefreshProperties.All)]
|
||||
[TypeConverter(typeof(ResolutionConverter))]
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayResolution")]
|
||||
public Size Resolution { get => PreviewPanel.Resolution; set => PreviewPanel.Resolution = value; }
|
||||
|
||||
[TypeConverter(typeof(PointFConverter))]
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayCenter")]
|
||||
public PointF Center { get => PreviewPanel.Center; set => PreviewPanel.Center = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayZoom")]
|
||||
public float Zoom { get => PreviewPanel.Zoom; set => PreviewPanel.Zoom = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayRotation")]
|
||||
public float Rotation { get => PreviewPanel.Rotation; set => PreviewPanel.Rotation = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayFlipHorizontal")]
|
||||
public bool FlipX { get => PreviewPanel.FlipX; set => PreviewPanel.FlipX = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayFlipVertical")]
|
||||
public bool FlipY { get => PreviewPanel.FlipY; set => PreviewPanel.FlipY = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryCustom")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayRenderSelected")]
|
||||
public bool RenderSelectedOnly { get => PreviewPanel.RenderSelectedOnly; set => PreviewPanel.RenderSelectedOnly = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryExport")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayShowAxis")]
|
||||
public bool ShowAxis { get => PreviewPanel.ShowAxis; set => PreviewPanel.ShowAxis = value; }
|
||||
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryExport")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayMaximumFrameRate")]
|
||||
public uint MaxFps { get => PreviewPanel.MaxFps; set => PreviewPanel.MaxFps = value; }
|
||||
|
||||
[Editor(typeof(SFMLColorEditor), typeof(UITypeEditor))]
|
||||
[TypeConverter(typeof(SFMLColorConverter))]
|
||||
[LocalizedCategory(typeof(Properties.Resources), "categoryExport")]
|
||||
[LocalizedDisplayName(typeof(Properties.Resources), "displayBackgroundColor")]
|
||||
public SFML.Graphics.Color BackgroundColor { get => PreviewPanel.BackgroundColor; set => PreviewPanel.BackgroundColor = value; }
|
||||
}
|
||||
}
|
||||
403
SpineViewer/Controls/SpinePreviewPanel.en.resx
Normal file
403
SpineViewer/Controls/SpinePreviewPanel.en.resx
Normal file
@@ -0,0 +1,403 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="panel_Render.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>157, 136</value>
|
||||
</data>
|
||||
<data name="panel_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>320, 320</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>641, 636</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>101, 598</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>438, 38</value>
|
||||
</data>
|
||||
<data name="imageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA8iMAAAJNU0Z0AUkBTAIBAQcB
|
||||
AAG4AQABuAEAAR8BAAEYAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABfAMAATADAAEBAQABIAYAAV0+
|
||||
AAMEAQUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/A1UB
|
||||
sWQAA1kB7wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/Ay0BRbcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9cAANEAXgDAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/swAB/wMAAf8DAAH/AwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/BwAB/wMAAf8DAAH/AwAB/wMAAf9XAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf+vAAH/AwAB/wNRAaQnAAH/AwAB/wMAAf8DAAH/MwAB/wMAAf8IAANOAZcDAAH/AwAB/wMAAf8D
|
||||
AAH/Ay4BSE8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB/+AAAxUBHQMAAf8DAAH/AwAB/y8AAf8DAAH/EwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf/kAAMmATgDAAH/AwAB/wMAAf8r
|
||||
AAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8DAAH/QwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/6wAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAANIAfYDAAH/AwAB/wMAAf8DAAH/AwQBBTsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/+8AAf8DAAH/AwAB/ycAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf/vAAH/AwAB/wMAAf8nAAH/AwAB/ygAAwcBCQMAAf8DAAH/AwAB/wMAAf8DYAHjLwAB/wMAAf8D
|
||||
AAH/SwAB/wMAAf8DAAH/7AADIAEtAwAB/wMAAf8nAAH/AwAB/zMAAf8DAAH/AwAB/wMAAf8DAAH/KwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/8wAB/wMAAf8nAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf9LAAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/PAADPwFsAwAB/wMAAf8nAAH/AwAB/wMAAf9L
|
||||
AAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB/0sAAf8D
|
||||
AAH/AwAB/5sAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/NAADCAEKAwAB/wMAAf8nAAH/AwAB
|
||||
/zAAA10BzgMAAf8DAAH/AwAB/wMAAf8EAScAAf8DAAH/AwAB/0sAAf8DAAH/AwAB/5QAAwUBBgMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/zMAAf8DAAH/AwAB/ycAAf8DAAH/LwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8vAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8nAAH/AwAB/ycAAf8DAAH/AwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8PAAH/AwAB/wMAAf8DFQEcLwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAAM9AWkDAAH/AwAB/wMAAf8DAAH/A0MBdjsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/5QAAwUBBgMAAf8DAAH/CwAB/wMAAf8DAAH/AxMBGjMAAf8DAAH/AwAB/ysAAf8DAAH/GwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf9DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wMbASYzAAH/AwAB/wMAAf8vAAH/AwAB/xMAAf8DAAH/AwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/SwAB
|
||||
/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMdASgkAANcAe4DAAH/AwAB
|
||||
/wMAAf8EAS8AAf8DAAH/CAADGAEhAwAB/wMAAf8DAAH/AwAB/wNcActPAAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/A2AB4wMAAf8DAAH/AwAB/wMAAf8DUAGfFwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf83AAH/AwAB/wcAAf8DAAH/AwAB/wMAAf8DAAH/VwAB/wMAAf8DAAH/AwAB/wMqAUAD
|
||||
KgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUAD
|
||||
AAH/AwAB/wMAAf8DAAH/mwAB/wMAAf8DAAH/Ax0BKQQAAwIBAwMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DBwEJWAAD
|
||||
WQHDAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/5wAAxIBFwMAAf8UAANKAYkDAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/AyEB+2cAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNbAcXIAANGAYADWgG/Ay4BSFQAA1oBv3QAA0YBgANaAb8DWgG/A1oBvwNaAb8DWgG/A1oB
|
||||
vwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DLgFIpwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADPQFpAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/EwAB/wMAAf8DAAH/LwAB/wMAAf8DAAH/KAADGQEiAwAB/wMAAf8jAAH/AwAB/wMAAf8oAAM/AW0D
|
||||
AAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADAwEEAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DAAH/AwAB/yQAA1YBtgMAAf8DAAH/AwAB
|
||||
/wMAAf8kAAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AwAB/wMAAf8DPwH4IwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/IAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8gAAM+AfkDAAH/AwAB/xwAA1oB
|
||||
8QMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/x8AAf8DAAH/AwAB/zcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxUB/jMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNZAbsYAANWAbUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DUQGeGAADPgH5AwAB/wMAAf8c
|
||||
AANaAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A1ABnRcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB
|
||||
/wMAAf8rAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAz4B+QMAAf8D
|
||||
AAH/HAADWgHxAwAB/wMAAf8DEQEWBAEDAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/zcAAf8D
|
||||
AAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswcAAf8D
|
||||
AAH/AwAB/wMAAf8jAAH/AwAB/wMAAf8DAAH/BwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAANWAbUDAAH/AwAB/wMzAVAHAAH/AwAB/wMAAf8DAAH/AwAB/xAAAz4B
|
||||
+QMAAf8DAAH/HAADWgHxAwAB/wMAAf8DEQEWCwAB/wMAAf8DAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wNWAbML
|
||||
AAH/AwAB/wMAAf8DFQH+GwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/Az0B
|
||||
aAgAA2AB2wMAAf8DAAH/AwAB/wMAAf8MAANWAbUDAAH/AwAB/wMzAVAIAANgAeMDAAH/AwAB/wMAAf8D
|
||||
AAH/DAADPgH5AwAB/wMAAf8cAANaAfEDAAH/AwAB/wMRARYMAAMzAVIDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/A1YBsw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/DAAD
|
||||
VAGrAwAB/wMAAf8DPQFoDAADJQE3AwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAzIB
|
||||
TwMAAf8DAAH/AwAB/wMAAf8IAAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxUB/gMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xAAAwwBDwMAAf8D
|
||||
SAH2DAADVAGrAwAB/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8D
|
||||
AAH/AwAB/wMAAf8EAAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFhgAA1oB6QMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/0cAAf8DAAH/AwAB/wMVAf4DAAH/AwAB/wMAAf8DAAH/LAADVAGrAwAB/wMAAf8DPQFoGwAB/wMAAf8D
|
||||
AAH/AwAB/wNdAc4DAAH/AwAB/wMzAVAbAAH/AwAB/wMAAf8DAAH/AykB+gMAAf8DAAH/HAADWgHxAwAB
|
||||
/wMAAf8DEQEWIwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8wAANUAasDAAH/AwAB/wM9AWgf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMwFQHwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/HAADWgHxAwAB
|
||||
/wMAAf8DEQEWJwAB/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/08AAf8DAAH/AwAB/wMAAf80AANUAasDAAH/AwAB/wM9AWgjAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMzAVAjAAH/AwAB/wMAAf8DAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFisAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxUB/jAAA1QBqwMAAf8DAAH/Az0BaB8AAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMzAVAf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8cAANaAfEDAAH/AwAB/wMRARYkAANcAdkDAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf9HAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/ywAA1QBqwMAAf8DAAH/Az0BaBsAAf8DAAH/AwAB/wMAAf8DWgHxAwAB
|
||||
/wMAAf8DMwFQGwAB/wMAAf8DAAH/AwAB/wMVAf4DAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFiMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8D
|
||||
AAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xcAAf8DWAG4DAADVAGrAwAB
|
||||
/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8DAAH/AwAB/wMAAf8E
|
||||
AAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFhgAAzABSgMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YB
|
||||
sw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DFQH+DwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
PQFoEwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAwkBDAMAAf8DAAH/AwAB/wMAAf8I
|
||||
AAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB/wMAAf8DAAH/AyoB/QMAAf8D
|
||||
AAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/JwAB/wMAAf8D
|
||||
VgGzCwAB/wMAAf8DAAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8MAANUAasDAAH/AwAB
|
||||
/wM9AWgIAAM6AWADAAH/AwAB/wMAAf8DAAH/DAADVgG1AwAB/wMAAf8DMwFQCAADSwGMAwAB/wMAAf8D
|
||||
AAH/AwAB/wwAAz4B+QMAAf8DAAH/HAADWgHxAwAB/wMAAf8DEQEWDAADBwEJAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8HAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wNWAbMHAAH/AwAB/wMAAf8DAAH/IwAB/wMAAf8DAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wwAA1QBqwMAAf8DAAH/Az0BaAcAAf8DAAH/AwAB/wMAAf8DAAH/EAADVgG1AwAB/wMAAf8DMwFQBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAAM+AfkDAAH/AwAB/xwAA1oB8QMAAf8DAAH/AxEBFgsAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A08BmQsAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB/wMAAf8rAAH/AwAB/wMAAf8DFQH+AwAB
|
||||
/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8DAAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB
|
||||
/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAz4B+QMAAf8DAAH/HAADWgHxAwAB/wMAAf8DEQEWBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DUwH0GAADVgG1AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A10B7BgAAz4B+QMAAf8DAAH/HAADWgHxAwAB/wMAAf8DYQHrAwAB/wMAAf8DAAH/AwAB
|
||||
/wNTAfQXAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DQwF3HAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8DMAFMHAADPgH5AwAB/wMAAf8c
|
||||
AANaAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8fAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8DKgFAAyoB
|
||||
QAMqAUADAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8DKgFAAyoBQAMqAUADAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8bAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwYBCCAAA1YBtgMAAf8DAAH/AwAB/wMAAf8DAgEDIAAD
|
||||
PgH5AwAB/wMAAf8cAANaAfEDAAH/AwAB/wMAAf8DAAH/AwAB/yMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xQAA0wBkAMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/y8AAf8DAAH/AwAB/ygAAzYBWAMAAf8DAAH/IwAB
|
||||
/wMAAf8DAAH/Aw0BESQAA1UBrQMAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8sAANaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DFQEcGAAD
|
||||
TwGZA1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvxgAA04BlzQAA0sBjTAAAwwBDygAA1ABmjAAAygB
|
||||
PEAAAzgBWwNaAb8DWgG/A1oBvwMwAUwYAANEAXoDWgG/A1oBvwNaAb8DIAEtHAABQgFNAT4HAAE+AwAB
|
||||
KAMAAXwDAAEwAwABAQEAAQEGAAEDFgAD/wEAAf8B4AEHAf8B+AE/Av8B4AIAAXgEAAH/AcABAQH/AfgB
|
||||
HwL/AcACAAF4BAAB/wGDAeAB/wH5AQcC/wHAAgABOAQAAf8BjwH4AX8B+QGBAv8BxwH/Af4BOAQAAv8B
|
||||
/AE/AfkB4AL/AccB/wH+ATgEAAL/Af4BHwH5AfgBPwH/AccB/wH+ATgEAAP/AR8B+QH8AQ8B/wHHAf8B
|
||||
/gE4BAAD/wGPAfkB/wEHAf8BxwH/Af4BOAQAA/8BjwH5Af8BgQH/AccB/wH+ATgEAAP/AY8B+QH/AeAB
|
||||
/wHHAf8B/gE4BAAD/wHPAfkB/wH4AX8BxwH/Af4BOAQAA/8BzwH5Af8B/AF/AccB/wH+ATgEAAP/Ac8B
|
||||
+QH/AfgBfwHHAf8B/gE4BAAB8AEPAf8BjwH5Af8B4AF/AccB/wH+ATgEAAHgAQcB/wGPAfkB/wHBAf8B
|
||||
xwH/Af4BOAQAAeABBwH/AY8B+QH/AQcB/wHHAf8B/gE4BAAB4wGHAf8BHwH5AfwBDwH/AccB/wH+ATgE
|
||||
AAHjAQ8B/wEfAfkB+AE/Af8BxwH/Af4BOAQAAeIBHwH+AT8B+QHgAv8BxwH/Af4BOAQAAeABDwH4AT8B
|
||||
+QGBAv8BxwH/Af4BOAQAAeABAwHgAf8B+QEHAv8BwAIAATgEAAHwAYABAQH/AfgBDwL/AcACAAF4BAAB
|
||||
8wHgAQcB/wH4AT8C/wHgAgABeAQAAf8B/gE/Af8B/gP/AfgBAAEBAfgEAAHwAQcBwAEPAR8B/AF/AeMB
|
||||
/AF/AeMB/wHwAR4BAwLwAQcBwAEOAQ8B+AE/AeMB+AEfAeMB/wHgAQwBAQLwAX8B/gEOAQcB+AEfAeMB
|
||||
+AEPAeMB/wHgAQwBAQLwAT8B/AEOAQEB+AEHAeMB+AEDAeMB/wHjAYwBcQLwAR8B+AEOAQAB+AEDAeMB
|
||||
+AEBAeMB/wHjAYwBcQHwAfEBDwHwAY4BEAF4AUEB4wH4AWAB4wH/AeMBjAFxAfAB8QGHAeEBjgEYATgB
|
||||
YAHjAfgBcAEjAf8B4wGMAXEB8AHxAsMBjgEcARgBcAFjAfgBfAEDAf8B4wGMAXEB8AHzAeEBhwGOAR8B
|
||||
CAF8ASMB+AF+AQMB/wHjAYwBcQHwAf8B8AEPAf4BHwGAAX4BAwH4AX8BgwH/AeMBjAFxAfAB/wH4AR8B
|
||||
/gEfAcABfwEDAfgBfwHDAf8B4wGMAXEB8AH/AfwBPwH+AR8B4AF/AYMB+AF/AeMB/wHjAYwBcQHwAf8B
|
||||
+AEfAf4BHwHAAX8BAwH4AX8BwwH/AeMBjAFxAfAB/wHwAQ8B/gEfAYABfgEDAfgBfwGDAf8B4wGMAXEB
|
||||
8AHzAeEBhwHOAR8BCAF8ASMB+AF+AQMB/wHjAYwBcQHwAfECwwGOAR4BGAFwAWMB+AF8AQMB/wHjAYwB
|
||||
cQHwAfEBhwHhAY4BGAE4AWAB4wH4AXABIwH/AeMBjAFxAfAB8QEPAfABjgEQAXgBQQHjAfgBYAFjAf8B
|
||||
4wGMAXEC8AEfAfgBDgEAAfgBAwHjAfgBQQHjAf8B4wGMAXEC8AE/AfwBDgEBAfgBBwHjAfgBAwHjAf8B
|
||||
4wGMAXEC8AF/Af4BDgEDAfgBDwHjAfgBDwHjAf8B4AEMAQEC8AEHAeABDgEHAfgBHwHjAfgBHwHjAf8B
|
||||
4AEMAQEC8AEHAcABDwEfAfwBfwHjAfwBPwHjAf8B8AEeAQMB8AH4AQcB4AEfAb8B/gH/AfcB/gH/AfcB
|
||||
/wH4AT8BBwHwCw==
|
||||
</value>
|
||||
</data>
|
||||
<data name="button_Stop.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>3, 2</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Stop.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_Stop.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_Stop.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_Stop.ToolTip" xml:space="preserve">
|
||||
<value>Stop playback and reset time.</value>
|
||||
</data>
|
||||
<data name="button_Restart.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>76, 2</value>
|
||||
</data>
|
||||
<data name="button_Restart.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_Restart.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_Restart.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_Restart.ToolTip" xml:space="preserve">
|
||||
<value>Play from the beginning.</value>
|
||||
</data>
|
||||
<data name="button_Start.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>149, 2</value>
|
||||
</data>
|
||||
<data name="button_Start.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_Start.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_Start.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_Start.ToolTip" xml:space="preserve">
|
||||
<value>Play/Pause</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>222, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.ToolTip" xml:space="preserve">
|
||||
<value>Fast forward 1 frame</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>295, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.ToolTip" xml:space="preserve">
|
||||
<value>Fast forward 10 frames.</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>368, 2</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>15, 2, 15, 2</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>67, 34</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.ToolTip" xml:space="preserve">
|
||||
<value>Fullscreen preview.</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>641, 598</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>641, 598</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>11, 24</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>3, 2, 3, 2</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>641, 636</value>
|
||||
</data>
|
||||
</root>
|
||||
765
SpineViewer/Controls/SpinePreviewPanel.resx
Normal file
765
SpineViewer/Controls/SpinePreviewPanel.resx
Normal file
@@ -0,0 +1,765 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="button_ForwardStep.ImageKey" xml:space="preserve">
|
||||
<value>forward-step</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="spinePreviewFullScreenForm.Visible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardFast.Name" xml:space="preserve">
|
||||
<value>button_ForwardFast</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardFast.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>panel_ViewContainer.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Restart.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="button_Start.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name=">>toolTip.Name" xml:space="preserve">
|
||||
<value>toolTip</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Start.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Start.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.ImageKey" xml:space="preserve">
|
||||
<value>arrows-maximize</value>
|
||||
</data>
|
||||
<data name=">>spinePreviewFullScreenForm.Type" xml:space="preserve">
|
||||
<value>SpineViewer.Forms.SpinePreviewFullScreenForm, SpineViewer, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>wallpaperForm.Name" xml:space="preserve">
|
||||
<value>wallpaperForm</value>
|
||||
</data>
|
||||
<data name="button_Restart.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>466, 530</value>
|
||||
</data>
|
||||
<data name=">>button_Restart.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_Restart.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>65, 2</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="button_Start.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name=">>panel_RenderContainer.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name="button_Start.ImageKey" xml:space="preserve">
|
||||
<value>pause</value>
|
||||
</data>
|
||||
<data name="panel_Render.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>114, 113</value>
|
||||
</data>
|
||||
<data name="button_Start.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>panel_ViewContainer.Name" xml:space="preserve">
|
||||
<value>panel_ViewContainer</value>
|
||||
</data>
|
||||
<data name="button_Stop.ToolTip" xml:space="preserve">
|
||||
<value>停止播放并重置时间到初始</value>
|
||||
</data>
|
||||
<data name="button_Restart.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name=">>panel_Render.Name" xml:space="preserve">
|
||||
<value>panel_Render</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>SpinePreviewPanel</value>
|
||||
</data>
|
||||
<data name=">>button_Stop.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardFast.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>panel_Render.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="spinePreviewFullScreenForm.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>2560, 1440</value>
|
||||
</data>
|
||||
<data name=">>panel_Render.Parent" xml:space="preserve">
|
||||
<value>panel_RenderContainer</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>panel_RenderContainer.Parent" xml:space="preserve">
|
||||
<value>panel_ViewContainer</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="wallpaperForm.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name=">>button_ForwardStep.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_ForwardStep.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="panel_Render.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>button_Stop.Name" xml:space="preserve">
|
||||
<value>button_Stop</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button_FullScreen.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>imageList.Name" xml:space="preserve">
|
||||
<value>imageList</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardFast.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Stop.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>466, 492</value>
|
||||
</data>
|
||||
<data name="button_Restart.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>254, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Start.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>378, 38</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="panel_Render.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardStep.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name=">>imageList.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_Restart.ToolTip" xml:space="preserve">
|
||||
<value>从头开始播放</value>
|
||||
</data>
|
||||
<data name=">>button_FullScreen.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="panel_Render.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="button_ForwardFast.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="button_Start.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>128, 2</value>
|
||||
</data>
|
||||
<data name="spinePreviewFullScreenForm.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name=">>button_Start.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Restart.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>466, 492</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.ToolTip" xml:space="preserve">
|
||||
<value>快进 1 帧</value>
|
||||
</data>
|
||||
<data name=">>button_Stop.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.ToolTip" xml:space="preserve">
|
||||
<value>快进 10 帧</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>None</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>317, 2</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardStep.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="button_ForwardFast.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>button_Restart.Name" xml:space="preserve">
|
||||
<value>button_Restart</value>
|
||||
</data>
|
||||
<data name="button_Stop.ImageKey" xml:space="preserve">
|
||||
<value>stop</value>
|
||||
</data>
|
||||
<data name="panel_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>233, 267</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="wallpaperForm.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>Manual</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>panel_ViewContainer.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_Stop.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name=">>wallpaperForm.Type" xml:space="preserve">
|
||||
<value>SpineViewer.WallpaperForm, SpineViewer, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name="button_Stop.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 2</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.ToolTip" xml:space="preserve">
|
||||
<value>全屏预览</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Stop.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>panel_RenderContainer.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Stop.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="flowLayoutPanel1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="panel_ViewContainer" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="button_FullScreen.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>button_FullScreen.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="button_Stop.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_Restart.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Stop.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name=">>button_ForwardStep.Name" xml:space="preserve">
|
||||
<value>button_ForwardStep</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>191, 2</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>44, 492</value>
|
||||
</data>
|
||||
<data name="$this.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="imageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA9CMAAAJNU0Z0AUkBTAIBAQcB
|
||||
AAGkAQABrAEAAR8BAAEYAQAE/wEhARAI/wFCAU0BNgcAATYDAAEoAwABfAMAATADAAEBAQABIAYAAV0+
|
||||
AAMEAQUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/A1UB
|
||||
sWQAA1kB7wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/Ay0BRbcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9cAANEAXgDAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/swAB/wMAAf8DAAH/AwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/BwAB/wMAAf8DAAH/AwAB/wMAAf9XAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf+vAAH/AwAB/wNRAaQnAAH/AwAB/wMAAf8DAAH/MwAB/wMAAf8IAANOAZcDAAH/AwAB/wMAAf8D
|
||||
AAH/Ay4BSE8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB/+AAAxUBHQMAAf8DAAH/AwAB/y8AAf8DAAH/EwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf/kAAMmATgDAAH/AwAB/wMAAf8r
|
||||
AAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8DAAH/QwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/6wAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAANEAfYDAAH/AwAB/wMAAf8DAAH/AwQBBTsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/+8AAf8DAAH/AwAB/ycAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf/vAAH/AwAB/wMAAf8nAAH/AwAB/ygAAwcBCQMAAf8DAAH/AwAB/wMAAf8DYAHjLwAB/wMAAf8D
|
||||
AAH/SwAB/wMAAf8DAAH/7AADIAEtAwAB/wMAAf8nAAH/AwAB/zMAAf8DAAH/AwAB/wMAAf8DAAH/KwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/8wAB/wMAAf8nAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf9LAAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/PAADPwFsAwAB/wMAAf8nAAH/AwAB/wMAAf9L
|
||||
AAH/AwAB/wMAAf/zAAH/AwAB/ycAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB/0sAAf8D
|
||||
AAH/AwAB/5sAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/NAADCAEKAwAB/wMAAf8nAAH/AwAB
|
||||
/zAAA10BzgMAAf8DAAH/AwAB/wMAAf8EAScAAf8DAAH/AwAB/0sAAf8DAAH/AwAB/5QAAwUBBgMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/zMAAf8DAAH/AwAB/ycAAf8DAAH/LwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8vAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8nAAH/AwAB/ycAAf8DAAH/AwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/SwAB/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8PAAH/AwAB/wMAAf8DFQEcLwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8cAAM9AWkDAAH/AwAB/wMAAf8DAAH/A0MBdjsAAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/5QAAwUBBgMAAf8DAAH/CwAB/wMAAf8DAAH/AxMBGjMAAf8DAAH/AwAB/ysAAf8DAAH/GwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf9DAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf+UAAMFAQYDAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wMbASYzAAH/AwAB/wMAAf8vAAH/AwAB/xMAAf8DAAH/AwAB/wMAAf8DAAH/SwAB/wMAAf8DAAH/SwAB
|
||||
/wMAAf8DAAH/lAADBQEGAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMdASgkAANaAe4DAAH/AwAB
|
||||
/wMAAf8EAS8AAf8DAAH/CAADGAEhAwAB/wMAAf8DAAH/AwAB/wNcActPAAH/AwAB/wMAAf9LAAH/AwAB
|
||||
/wMAAf+UAAMFAQYDAAH/AwAB/wMAAf8DAAH/A2AB4wMAAf8DAAH/AwAB/wMAAf8DUAGfFwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf83AAH/AwAB/wcAAf8DAAH/AwAB/wMAAf8DAAH/VwAB/wMAAf8DAAH/AwAB/wMqAUAD
|
||||
KgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUADKgFAAyoBQAMqAUAD
|
||||
AAH/AwAB/wMAAf8DAAH/mwAB/wMAAf8DAAH/Ax0BKQQAAwIBAwMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DBwEJWAAD
|
||||
WQHDAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/5wAAxIBFwMAAf8UAANKAYkDAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf9DAAH/AwAB/wMAAf8DAAH/AyEB+2cAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNbAcXIAANGAYADWgG/Ay4BSFQAA1oBv3QAA0YBgANaAb8DWgG/A1oBvwNaAb8DWgG/A1oB
|
||||
vwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DLgFIpwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADPQFpAwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/EwAB/wMAAf8DAAH/LwAB/wMAAf8DAAH/KAADGQEiAwAB/wMAAf8jAAH/AwAB/wMAAf8oAAM/AW0D
|
||||
AAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/KwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/FAADAwEEAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DAAH/AwAB/yQAA1YBtgMAAf8DAAH/AwAB
|
||||
/wMAAf8kAAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AwAB/wMAAf8DPQH4IwAB/wMAAf8DAAH/NwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8DAAH/AwAB/wMAAf87AAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/IAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8gAAM4AfkDAAH/AwAB/xwAA1gB
|
||||
8QMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/x8AAf8DAAH/AwAB/zcAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/ycAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxMB/jMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wNZAbsYAANWAbUDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DUQGeGAADOAH5AwAB/wMAAf8c
|
||||
AANYAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A1ABnRcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB
|
||||
/wMAAf8rAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAzgB+QMAAf8D
|
||||
AAH/HAADWAHxAwAB/wMAAf8DEQEWBAEDAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/zcAAf8D
|
||||
AAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswcAAf8D
|
||||
AAH/AwAB/wMAAf8jAAH/AwAB/wMAAf8DAAH/BwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAANWAbUDAAH/AwAB/wMzAVAHAAH/AwAB/wMAAf8DAAH/AwAB/xAAAzgB
|
||||
+QMAAf8DAAH/HAADWAHxAwAB/wMAAf8DEQEWCwAB/wMAAf8DAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wNWAbML
|
||||
AAH/AwAB/wMAAf8DEwH+GwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wwAA1QBqwMAAf8DAAH/Az0B
|
||||
aAgAA2AB2wMAAf8DAAH/AwAB/wMAAf8MAANWAbUDAAH/AwAB/wMzAVAIAANgAeMDAAH/AwAB/wMAAf8D
|
||||
AAH/DAADOAH5AwAB/wMAAf8cAANYAfEDAAH/AwAB/wMRARYMAAMzAVIDAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wcAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/A1YBsw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/DAAD
|
||||
VAGrAwAB/wMAAf8DPQFoDAADJQE3AwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAzIB
|
||||
TwMAAf8DAAH/AwAB/wMAAf8IAAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxMB/gMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB
|
||||
/wMAAf8DAAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xAAAwwBDwMAAf8D
|
||||
RAH2DAADVAGrAwAB/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8D
|
||||
AAH/AwAB/wMAAf8EAAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFhgAA1oB6QMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB
|
||||
/0cAAf8DAAH/AwAB/wMTAf4DAAH/AwAB/wMAAf8DAAH/LAADVAGrAwAB/wMAAf8DPQFoGwAB/wMAAf8D
|
||||
AAH/AwAB/wNdAc4DAAH/AwAB/wMzAVAbAAH/AwAB/wMAAf8DAAH/AycB+gMAAf8DAAH/HAADWAHxAwAB
|
||||
/wMAAf8DEQEWIwAB/wMAAf8DAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf9LAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8wAANUAasDAAH/AwAB/wM9AWgf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DMwFQHwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/HAADWAHxAwAB
|
||||
/wMAAf8DEQEWJwAB/wMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/08AAf8DAAH/AwAB/wMAAf80AANUAasDAAH/AwAB/wM9AWgjAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMzAVAjAAH/AwAB/wMAAf8DAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFisAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/0sAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AxMB/jAAA1QBqwMAAf8DAAH/Az0BaB8AAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMzAVAf
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8cAANYAfEDAAH/AwAB/wMRARYkAANcAdkDAAH/AwAB/wMAAf83
|
||||
AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB/wMAAf9HAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/ywAA1QBqwMAAf8DAAH/Az0BaBsAAf8DAAH/AwAB/wMAAf8DWAHxAwAB
|
||||
/wMAAf8DMwFQGwAB/wMAAf8DAAH/AwAB/wMTAf4DAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFiMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8D
|
||||
AAH/JwAB/wMAAf8XAAH/AwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/AwAB/xcAAf8DWAG4DAADVAGrAwAB
|
||||
/wMAAf8DPQFoFwAB/wMAAf8DAAH/AwAB/wQAA1YBtQMAAf8DAAH/AzMBUBcAAf8DAAH/AwAB/wMAAf8E
|
||||
AAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFhgAAzABSgMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YB
|
||||
sw8AAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf8DEwH+DwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
PQFoEwAB/wMAAf8DAAH/AwAB/wgAA1YBtQMAAf8DAAH/AzMBUAwAAwkBDAMAAf8DAAH/AwAB/wMAAf8I
|
||||
AAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFhcAAf8DAAH/AwAB/wMAAf8DAAH/AyYB/QMAAf8D
|
||||
AAH/NwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/CwAB/wMAAf8DAAH/DwAB/wMAAf8DAAH/JwAB/wMAAf8D
|
||||
VgGzCwAB/wMAAf8DAAH/AwAB/xsAAf8DAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8MAANUAasDAAH/AwAB
|
||||
/wM9AWgIAAM6AWADAAH/AwAB/wMAAf8DAAH/DAADVgG1AwAB/wMAAf8DMwFQCAADSwGMAwAB/wMAAf8D
|
||||
AAH/AwAB/wwAAzgB+QMAAf8DAAH/HAADWAHxAwAB/wMAAf8DEQEWDAADBwEJAwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8HAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wNWAbMHAAH/AwAB/wMAAf8DAAH/IwAB/wMAAf8DAAH/AwAB/wcAAf8DAAH/AwAB
|
||||
/wwAA1QBqwMAAf8DAAH/Az0BaAcAAf8DAAH/AwAB/wMAAf8DAAH/EAADVgG1AwAB/wMAAf8DMwFQBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8QAAM4AfkDAAH/AwAB/xwAA1gB8QMAAf8DAAH/AxEBFgsAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A08BmQsAAf8DAAH/AwAB/zcAAf8DAAH/AwAB/w8AAf8DAAH/AwAB/wsAAf8DAAH/AwAB
|
||||
/w8AAf8DAAH/AwAB/ycAAf8DAAH/A1YBswMAAf8DAAH/AwAB/wMAAf8rAAH/AwAB/wMAAf8DEwH+AwAB
|
||||
/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8DPQFoAwAB/wMAAf8DAAH/AwAB/wMAAf8UAANWAbUDAAH/AwAB
|
||||
/wMzAVADAAH/AwAB/wMAAf8DAAH/AwAB/xQAAzgB+QMAAf8DAAH/HAADWAHxAwAB/wMAAf8DEQEWBwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8TAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB
|
||||
/wMAAf8PAAH/AwAB/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8zAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DTwH0GAADVgG1AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/A10B7BgAAzgB+QMAAf8DAAH/HAADWAHxAwAB/wMAAf8DYQHrAwAB/wMAAf8DAAH/AwAB
|
||||
/wNPAfQXAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8PAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8PAAH/AwAB
|
||||
/wMAAf8nAAH/AwAB/wMAAf8DAAH/AwAB/zsAAf8DAAH/AwAB/wMAAf8DAAH/DAADVAGrAwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DQwF3HAADVgG1AwAB/wMAAf8DAAH/AwAB/wMAAf8DMAFMHAADOAH5AwAB/wMAAf8c
|
||||
AANYAfEDAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8fAAH/AwAB/wMAAf83AAH/AwAB/wMAAf8DKgFAAyoB
|
||||
QAMqAUADAAH/AwAB/wMAAf8LAAH/AwAB/wMAAf8DKgFAAyoBQAMqAUADAAH/AwAB/wMAAf8nAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8bAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/wMAAf8MAANUAasDAAH/AwAB/wMAAf8DAAH/AwYBCCAAA1YBtgMAAf8DAAH/AwAB/wMAAf8DAgEDIAAD
|
||||
OAH5AwAB/wMAAf8cAANYAfEDAAH/AwAB/wMAAf8DAAH/AwAB/yMAAf8DAAH/AwAB/zcAAf8DAAH/AwAB
|
||||
/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wsAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB
|
||||
/ycAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xQAA0wBkAMAAf8DAAH/AwAB/wMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8DAAH/AwAB/y8AAf8DAAH/AwAB/ygAAzYBWAMAAf8DAAH/IwAB
|
||||
/wMAAf8DAAH/Aw0BESQAA1UBrQMAAf8DAAH/OwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xMAAf8D
|
||||
AAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8sAANaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvwNaAb8DFQEcGAAD
|
||||
TwGZA1oBvwNaAb8DWgG/A1oBvwNaAb8DWgG/A1oBvxgAA04BlzQAA0sBjTAAAwwBDygAA1ABmjAAAygB
|
||||
PEAAAzgBWwNaAb8DWgG/A1oBvwMwAUwYAANEAXoDWgG/A1oBvwNaAb8DIAEtHAABQgFNAT4HAAE+AwAB
|
||||
KAMAAXwDAAEwAwABAQEAAQEGAAEDFgAD/wEAAf8B4AEHAf8B+AE/Av8B4AIAAXgEAAH/AcABAQH/AfgB
|
||||
HwL/AcACAAF4BAAB/wGDAeAB/wH5AQcC/wHAAgABOAQAAf8BjwH4AX8B+QGBAv8BxwH/Af4BOAQAAv8B
|
||||
/AE/AfkB4AL/AccB/wH+ATgEAAL/Af4BHwH5AfgBPwH/AccB/wH+ATgEAAP/AR8B+QH8AQ8B/wHHAf8B
|
||||
/gE4BAAD/wGPAfkB/wEHAf8BxwH/Af4BOAQAA/8BjwH5Af8BgQH/AccB/wH+ATgEAAP/AY8B+QH/AeAB
|
||||
/wHHAf8B/gE4BAAD/wHPAfkB/wH4AX8BxwH/Af4BOAQAA/8BzwH5Af8B/AF/AccB/wH+ATgEAAP/Ac8B
|
||||
+QH/AfgBfwHHAf8B/gE4BAAB8AEPAf8BjwH5Af8B4AF/AccB/wH+ATgEAAHgAQcB/wGPAfkB/wHBAf8B
|
||||
xwH/Af4BOAQAAeABBwH/AY8B+QH/AQcB/wHHAf8B/gE4BAAB4wGHAf8BHwH5AfwBDwH/AccB/wH+ATgE
|
||||
AAHjAQ8B/wEfAfkB+AE/Af8BxwH/Af4BOAQAAeIBHwH+AT8B+QHgAv8BxwH/Af4BOAQAAeABDwH4AT8B
|
||||
+QGBAv8BxwH/Af4BOAQAAeABAwHgAf8B+QEHAv8BwAIAATgEAAHwAYABAQH/AfgBDwL/AcACAAF4BAAB
|
||||
8wHgAQcB/wH4AT8C/wHgAgABeAQAAf8B/gE/Af8B/gP/AfgBAAEBAfgEAAHwAQcBwAEPAR8B/AF/AeMB
|
||||
/AF/AeMB/wHwAR4BAwLwAQcBwAEOAQ8B+AE/AeMB+AEfAeMB/wHgAQwBAQLwAX8B/gEOAQcB+AEfAeMB
|
||||
+AEPAeMB/wHgAQwBAQLwAT8B/AEOAQEB+AEHAeMB+AEDAeMB/wHjAYwBcQLwAR8B+AEOAQAB+AEDAeMB
|
||||
+AEBAeMB/wHjAYwBcQHwAfEBDwHwAY4BEAF4AUEB4wH4AWAB4wH/AeMBjAFxAfAB8QGHAeEBjgEYATgB
|
||||
YAHjAfgBcAEjAf8B4wGMAXEB8AHxAsMBjgEcARgBcAFjAfgBfAEDAf8B4wGMAXEB8AHzAeEBhwGOAR8B
|
||||
CAF8ASMB+AF+AQMB/wHjAYwBcQHwAf8B8AEPAf4BHwGAAX4BAwH4AX8BgwH/AeMBjAFxAfAB/wH4AR8B
|
||||
/gEfAcABfwEDAfgBfwHDAf8B4wGMAXEB8AH/AfwBPwH+AR8B4AF/AYMB+AF/AeMB/wHjAYwBcQHwAf8B
|
||||
+AEfAf4BHwHAAX8BAwH4AX8BwwH/AeMBjAFxAfAB/wHwAQ8B/gEfAYABfgEDAfgBfwGDAf8B4wGMAXEB
|
||||
8AHzAeEBhwHOAR8BCAF8ASMB+AF+AQMB/wHjAYwBcQHwAfECwwGOAR4BGAFwAWMB+AF8AQMB/wHjAYwB
|
||||
cQHwAfEBhwHhAY4BGAE4AWAB4wH4AXABIwH/AeMBjAFxAfAB8QEPAfABjgEQAXgBQQHjAfgBYAFjAf8B
|
||||
4wGMAXEC8AEfAfgBDgEAAfgBAwHjAfgBQQHjAf8B4wGMAXEC8AE/AfwBDgEBAfgBBwHjAfgBAwHjAf8B
|
||||
4wGMAXEC8AF/Af4BDgEDAfgBDwHjAfgBDwHjAf8B4AEMAQEC8AEHAeABDgEHAfgBHwHjAfgBHwHjAf8B
|
||||
4AEMAQEC8AEHAcABDwEfAfwBfwHjAfwBPwHjAf8B8AEeAQMB8AH4AQcB4AEfAb8B/gH/AfcB/gH/AfcB
|
||||
/wH4AT8BBwHwFgAL
|
||||
</value>
|
||||
</data>
|
||||
<data name="spinePreviewFullScreenForm.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>Manual</value>
|
||||
</data>
|
||||
<data name="button_Restart.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>panel_Render.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_Stop.Parent" xml:space="preserve">
|
||||
<value>flowLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_FullScreen.Name" xml:space="preserve">
|
||||
<value>button_FullScreen</value>
|
||||
</data>
|
||||
<data name=">>button_Start.Name" xml:space="preserve">
|
||||
<value>button_Start</value>
|
||||
</data>
|
||||
<data name="button_Start.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_Start.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>panel_ViewContainer.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="panel_RenderContainer.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="button_Restart.ImageKey" xml:space="preserve">
|
||||
<value>rotate-left</value>
|
||||
</data>
|
||||
<data name="button_Restart.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name="wallpaperForm.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name=">>panel_RenderContainer.Name" xml:space="preserve">
|
||||
<value>panel_RenderContainer</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name=">>flowLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="wallpaperForm.Visible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="button_Start.ToolTip" xml:space="preserve">
|
||||
<value>开始/暂停</value>
|
||||
</data>
|
||||
<data name="button_Start.BackgroundImageLayout" type="System.Windows.Forms.ImageLayout, System.Windows.Forms">
|
||||
<value>Center</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ToolTip" xml:space="preserve">
|
||||
<value />
|
||||
</data>
|
||||
<data name="button_ForwardFast.ImageKey" xml:space="preserve">
|
||||
<value>forward-fast</value>
|
||||
</data>
|
||||
<data name=">>toolTip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolTip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_FullScreen.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>59, 34</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>466, 530</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 2, 11, 2</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="button_ForwardFast.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_ForwardStep.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="flowLayoutPanel1.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>spinePreviewFullScreenForm.Name" xml:space="preserve">
|
||||
<value>spinePreviewFullScreenForm</value>
|
||||
</data>
|
||||
<data name="panel_ViewContainer.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<metadata name="spinePreviewFullScreenForm.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>307, 18</value>
|
||||
</metadata>
|
||||
<metadata name="wallpaperForm.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>618, 18</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="imageList.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>165, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
63
SpineViewer/Controls/SpinePreviewer.Designer.cs
generated
63
SpineViewer/Controls/SpinePreviewer.Designer.cs
generated
@@ -1,63 +0,0 @@
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
partial class SpinePreviewer
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 组件设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
panel = new Panel();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel
|
||||
//
|
||||
panel.BackColor = SystemColors.ControlDarkDark;
|
||||
panel.Location = new Point(160, 160);
|
||||
panel.Margin = new Padding(0);
|
||||
panel.Name = "panel";
|
||||
panel.Size = new Size(320, 320);
|
||||
panel.TabIndex = 1;
|
||||
panel.MouseDown += panel_MouseDown;
|
||||
panel.MouseMove += panel_MouseMove;
|
||||
panel.MouseUp += panel_MouseUp;
|
||||
panel.MouseWheel += panel_MouseWheel;
|
||||
//
|
||||
// SpinePreviewer
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
BackColor = SystemColors.ControlDark;
|
||||
Controls.Add(panel);
|
||||
Name = "SpinePreviewer";
|
||||
Size = new Size(640, 640);
|
||||
SizeChanged += SpinePreviewer_SizeChanged;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel;
|
||||
}
|
||||
}
|
||||
@@ -1,465 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Security.Policy;
|
||||
using System.Diagnostics;
|
||||
using NLog.Targets;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
public partial class SpinePreviewer : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// 包装类, 用于 PropertyGrid 显示
|
||||
/// </summary>
|
||||
private class PreviewerProperty
|
||||
{
|
||||
private readonly SpinePreviewer previewer;
|
||||
|
||||
public PreviewerProperty(SpinePreviewer previewer) { this.previewer = previewer; }
|
||||
|
||||
[TypeConverter(typeof(SizeTypeConverter))]
|
||||
[Category("导出"), DisplayName("分辨率")]
|
||||
public Size Resolution { get => previewer.Resolution; set => previewer.Resolution = value; }
|
||||
|
||||
[TypeConverter(typeof(PointFTypeConverter))]
|
||||
[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 ShowAxis { get => previewer.ShowAxis; set => previewer.ShowAxis = value; }
|
||||
|
||||
[Category("预览"), DisplayName("显示包围盒")]
|
||||
public bool ShowBounds { get => previewer.ShowBounds; set => previewer.ShowBounds = value; }
|
||||
|
||||
[Category("预览"), DisplayName("最大帧率")]
|
||||
public uint MaxFps { get => previewer.MaxFps; set => previewer.MaxFps = value; }
|
||||
}
|
||||
|
||||
[Category("自定义"), Description("相关联的 SpineListView")]
|
||||
public SpineListView? SpineListView { get; set; }
|
||||
|
||||
[Category("自定义"), Description("用于显示画面属性的属性页")]
|
||||
public PropertyGrid? PropertyGrid
|
||||
{
|
||||
get => propertyGrid;
|
||||
set
|
||||
{
|
||||
propertyGrid = value;
|
||||
if (propertyGrid is not null)
|
||||
propertyGrid.SelectedObject = new PreviewerProperty(this);
|
||||
}
|
||||
}
|
||||
private PropertyGrid? propertyGrid;
|
||||
|
||||
public const float ZOOM_MAX = 1000f;
|
||||
public const float ZOOM_MIN = 0.001f;
|
||||
public const int BACKGROUND_CELL_SIZE = 10;
|
||||
|
||||
private static readonly SFML.Graphics.Color BackgroundColor = new(105, 105, 105);
|
||||
private static readonly SFML.Graphics.Color AxisColor = new(220, 220, 220);
|
||||
private static readonly SFML.Graphics.Color BoundsColor = new(120, 200, 0);
|
||||
|
||||
private readonly SFML.Graphics.VertexArray AxisVertex = new(SFML.Graphics.PrimitiveType.Lines, 2);
|
||||
private readonly SFML.Graphics.VertexArray BoundsRect = new(SFML.Graphics.PrimitiveType.LineStrip, 5);
|
||||
|
||||
private readonly SFML.Graphics.RenderWindow RenderWindow;
|
||||
private readonly SFML.System.Clock Clock = new();
|
||||
private SFML.System.Vector2f? draggingSrc = null;
|
||||
private Spine.Spine? draggingSpine = null;
|
||||
|
||||
private Task? task = null;
|
||||
private CancellationTokenSource? cancelToken = null;
|
||||
|
||||
/// <summary>
|
||||
/// 分辨率
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public Size Resolution
|
||||
{
|
||||
get => resolution;
|
||||
set
|
||||
{
|
||||
if (value.Width <= 0) value.Width = 100;
|
||||
if (value.Height <= 0) value.Height = 100;
|
||||
|
||||
float parentX = Width;
|
||||
float parentY = Height;
|
||||
float sizeX = value.Width;
|
||||
float sizeY = value.Height;
|
||||
|
||||
if ((sizeY / sizeX) < (parentY / parentX))
|
||||
{
|
||||
// 相同的 X, 子窗口 Y 更小
|
||||
sizeY = parentX * sizeY / sizeX;
|
||||
sizeX = parentX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 相同的 Y, 子窗口 X 更小
|
||||
sizeX = parentY * sizeX / sizeY;
|
||||
sizeY = parentY;
|
||||
}
|
||||
|
||||
// 必须通过 SFML 的方法调整窗口
|
||||
RenderWindow.Position = new((int)(parentX - sizeX) / 2, (int)(parentY - sizeY) / 2);
|
||||
RenderWindow.Size = new((uint)sizeX, (uint)sizeY);
|
||||
|
||||
// 将 view 的大小设置成于 resolution 相同的大小, 其余属性都不变
|
||||
var view = RenderWindow.GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
view.Size = new(value.Width * signX, value.Height * signY);
|
||||
RenderWindow.SetView(view);
|
||||
|
||||
resolution = value;
|
||||
}
|
||||
}
|
||||
private Size resolution = new(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// 画面中心点
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public PointF Center
|
||||
{
|
||||
get
|
||||
{
|
||||
var center = RenderWindow.GetView().Center;
|
||||
return new(center.X, center.Y);
|
||||
}
|
||||
set
|
||||
{
|
||||
var view = RenderWindow.GetView();
|
||||
view.Center = new(value.X, value.Y);
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画面缩放
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public float Zoom
|
||||
{
|
||||
get => resolution.Width / Math.Abs(RenderWindow.GetView().Size.X);
|
||||
set
|
||||
{
|
||||
value = Math.Clamp(value, ZOOM_MIN, ZOOM_MAX);
|
||||
var view = RenderWindow.GetView();
|
||||
var signX = Math.Sign(view.Size.X);
|
||||
var signY = Math.Sign(view.Size.Y);
|
||||
view.Size = new(resolution.Width / value * signX, resolution.Height / value * signY);
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 画面旋转
|
||||
/// </summary>
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public float Rotation
|
||||
{
|
||||
get => RenderWindow.GetView().Rotation;
|
||||
set
|
||||
{
|
||||
var view = RenderWindow.GetView();
|
||||
view.Rotation = value;
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 水平翻转
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool FlipX
|
||||
{
|
||||
get => RenderWindow.GetView().Size.X < 0;
|
||||
set
|
||||
{
|
||||
var view = RenderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.X > 0 && value || size.X < 0 && !value)
|
||||
size.X *= -1;
|
||||
view.Size = size;
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 垂直翻转
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool FlipY
|
||||
{
|
||||
get => RenderWindow.GetView().Size.Y < 0;
|
||||
set
|
||||
{
|
||||
var view = RenderWindow.GetView();
|
||||
var size = view.Size;
|
||||
if (size.Y > 0 && value || size.Y < 0 && !value)
|
||||
size.Y *= -1;
|
||||
view.Size = size;
|
||||
RenderWindow.SetView(view);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 显示坐标轴
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool ShowAxis { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 显示包围盒
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public bool ShowBounds { 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>
|
||||
/// RenderWindow.View
|
||||
/// </summary>
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
[Browsable(false)]
|
||||
public SFML.Graphics.View View { get => RenderWindow.GetView(); }
|
||||
|
||||
public SpinePreviewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
RenderWindow = new(panel.Handle);
|
||||
RenderWindow.SetActive(false);
|
||||
|
||||
// 设置默认参数
|
||||
Resolution = new(2048, 2048);
|
||||
Center = new(0, 0);
|
||||
FlipY = true;
|
||||
MaxFps = 30;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始预览
|
||||
/// </summary>
|
||||
public void StartPreview()
|
||||
{
|
||||
if (task is not null)
|
||||
return;
|
||||
cancelToken = new();
|
||||
task = Task.Run(RenderTask, cancelToken.Token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止预览
|
||||
/// </summary>
|
||||
public void StopPreview()
|
||||
{
|
||||
if (task is null || cancelToken is null)
|
||||
return;
|
||||
cancelToken.Cancel();
|
||||
task.Wait();
|
||||
cancelToken = null;
|
||||
task = null;
|
||||
}
|
||||
|
||||
private void SpinePreviewer_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (RenderWindow is null)
|
||||
return;
|
||||
|
||||
float parentX = Width;
|
||||
float parentY = Height;
|
||||
float sizeX = panel.Width;
|
||||
float sizeY = panel.Height;
|
||||
|
||||
if ((sizeY / sizeX) < (parentY / parentX))
|
||||
{
|
||||
// 相同的 X, 子窗口 Y 更小
|
||||
sizeY = parentX * sizeY / sizeX;
|
||||
sizeX = parentX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 相同的 Y, 子窗口 X 更小
|
||||
sizeX = parentY * sizeX / sizeY;
|
||||
sizeY = parentY;
|
||||
}
|
||||
|
||||
// 必须通过 SFML 的方法调整窗口
|
||||
RenderWindow.Position = new((int)(parentX - sizeX) / 2, (int)(parentY - sizeY) / 2);
|
||||
RenderWindow.Size = new((uint)sizeX, (uint)sizeY);
|
||||
}
|
||||
|
||||
private void panel_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
// 右键优先级高, 进入画面拖动模式, 需要重新记录源点
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
draggingSpine = null;
|
||||
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 not null)
|
||||
{
|
||||
lock (SpineListView.Spines)
|
||||
{
|
||||
foreach (var spine in SpineListView.Spines)
|
||||
{
|
||||
if (spine.Bounds.Contains(src))
|
||||
{
|
||||
draggingSpine = spine;
|
||||
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 (draggingSpine is not null)
|
||||
draggingSpine.Position += delta;
|
||||
draggingSrc = dst;
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
// 右键高优先级, 结束画面拖动模式
|
||||
if ((e.Button & MouseButtons.Right) != 0)
|
||||
{
|
||||
draggingSpine = null;
|
||||
SpineListView?.PropertyGrid?.Refresh();
|
||||
|
||||
draggingSrc = null;
|
||||
Cursor = Cursors.Default;
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
// 按下了左键并且右键是松开的
|
||||
else if ((e.Button & MouseButtons.Left) != 0 && (MouseButtons & MouseButtons.Right) == 0)
|
||||
{
|
||||
draggingSrc = null;
|
||||
draggingSpine = null;
|
||||
SpineListView?.PropertyGrid?.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
private void panel_MouseWheel(object sender, MouseEventArgs e)
|
||||
{
|
||||
Zoom *= (e.Delta > 0 ? 1.1f : 0.9f);
|
||||
PropertyGrid?.Refresh();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
foreach (var spine in SpineListView.Spines.Reverse())
|
||||
{
|
||||
spine.Update(delta);
|
||||
RenderWindow.Draw(spine);
|
||||
|
||||
if (ShowBounds)
|
||||
{
|
||||
var bounds = spine.Bounds;
|
||||
BoundsRect[0] = BoundsRect[4] = new(new(bounds.Left, bounds.Top), BoundsColor);
|
||||
BoundsRect[1] = new(new(bounds.Right, bounds.Top), BoundsColor);
|
||||
BoundsRect[2] = new(new(bounds.Right, bounds.Bottom), BoundsColor);
|
||||
BoundsRect[3] = new(new(bounds.Left, bounds.Bottom), BoundsColor);
|
||||
RenderWindow.Draw(BoundsRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RenderWindow.Display();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderWindow.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
255
SpineViewer/Controls/SpineViewPropertyGrid.Designer.cs
generated
Normal file
255
SpineViewer/Controls/SpineViewPropertyGrid.Designer.cs
generated
Normal file
@@ -0,0 +1,255 @@
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
partial class SpineViewPropertyGrid
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region 组件设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpineViewPropertyGrid));
|
||||
tabControl = new TabControl();
|
||||
tabPage_BaseInfo = new TabPage();
|
||||
propertyGrid_BaseInfo = new PropertyGrid();
|
||||
tabPage_Render = new TabPage();
|
||||
propertyGrid_Render = new PropertyGrid();
|
||||
tabPage_Transform = new TabPage();
|
||||
propertyGrid_Transform = new PropertyGrid();
|
||||
tabPage_Skin = new TabPage();
|
||||
propertyGrid_Skin = new PropertyGrid();
|
||||
contextMenuStrip_Skin = new ContextMenuStrip(components);
|
||||
toolStripMenuItem_ReloadSkins = new ToolStripMenuItem();
|
||||
tabPage_Slot = new TabPage();
|
||||
propertyGrid_Slot = new PropertyGrid();
|
||||
tabPage_Animation = new TabPage();
|
||||
propertyGrid_Animation = new PropertyGrid();
|
||||
contextMenuStrip_Animation = new ContextMenuStrip(components);
|
||||
toolStripMenuItem_AddAnimation = new ToolStripMenuItem();
|
||||
toolStripMenuItem_RemoveAnimation = new ToolStripMenuItem();
|
||||
tabPage_Debug = new TabPage();
|
||||
propertyGrid_Debug = new PropertyGrid();
|
||||
tabControl.SuspendLayout();
|
||||
tabPage_BaseInfo.SuspendLayout();
|
||||
tabPage_Render.SuspendLayout();
|
||||
tabPage_Transform.SuspendLayout();
|
||||
tabPage_Skin.SuspendLayout();
|
||||
contextMenuStrip_Skin.SuspendLayout();
|
||||
tabPage_Slot.SuspendLayout();
|
||||
tabPage_Animation.SuspendLayout();
|
||||
contextMenuStrip_Animation.SuspendLayout();
|
||||
tabPage_Debug.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// tabControl
|
||||
//
|
||||
resources.ApplyResources(tabControl, "tabControl");
|
||||
tabControl.Controls.Add(tabPage_BaseInfo);
|
||||
tabControl.Controls.Add(tabPage_Render);
|
||||
tabControl.Controls.Add(tabPage_Transform);
|
||||
tabControl.Controls.Add(tabPage_Skin);
|
||||
tabControl.Controls.Add(tabPage_Slot);
|
||||
tabControl.Controls.Add(tabPage_Animation);
|
||||
tabControl.Controls.Add(tabPage_Debug);
|
||||
tabControl.Multiline = true;
|
||||
tabControl.Name = "tabControl";
|
||||
tabControl.SelectedIndex = 0;
|
||||
tabControl.SizeMode = TabSizeMode.FillToRight;
|
||||
//
|
||||
// tabPage_BaseInfo
|
||||
//
|
||||
resources.ApplyResources(tabPage_BaseInfo, "tabPage_BaseInfo");
|
||||
tabPage_BaseInfo.BackColor = SystemColors.Control;
|
||||
tabPage_BaseInfo.Controls.Add(propertyGrid_BaseInfo);
|
||||
tabPage_BaseInfo.Name = "tabPage_BaseInfo";
|
||||
//
|
||||
// propertyGrid_BaseInfo
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_BaseInfo, "propertyGrid_BaseInfo");
|
||||
propertyGrid_BaseInfo.Name = "propertyGrid_BaseInfo";
|
||||
propertyGrid_BaseInfo.PropertySort = PropertySort.Alphabetical;
|
||||
propertyGrid_BaseInfo.ToolbarVisible = false;
|
||||
//
|
||||
// tabPage_Render
|
||||
//
|
||||
resources.ApplyResources(tabPage_Render, "tabPage_Render");
|
||||
tabPage_Render.BackColor = SystemColors.Control;
|
||||
tabPage_Render.Controls.Add(propertyGrid_Render);
|
||||
tabPage_Render.Name = "tabPage_Render";
|
||||
//
|
||||
// propertyGrid_Render
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Render, "propertyGrid_Render");
|
||||
propertyGrid_Render.Name = "propertyGrid_Render";
|
||||
propertyGrid_Render.PropertySort = PropertySort.Alphabetical;
|
||||
propertyGrid_Render.ToolbarVisible = false;
|
||||
//
|
||||
// tabPage_Transform
|
||||
//
|
||||
resources.ApplyResources(tabPage_Transform, "tabPage_Transform");
|
||||
tabPage_Transform.BackColor = SystemColors.Control;
|
||||
tabPage_Transform.Controls.Add(propertyGrid_Transform);
|
||||
tabPage_Transform.Name = "tabPage_Transform";
|
||||
//
|
||||
// propertyGrid_Transform
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Transform, "propertyGrid_Transform");
|
||||
propertyGrid_Transform.Name = "propertyGrid_Transform";
|
||||
propertyGrid_Transform.PropertySort = PropertySort.Alphabetical;
|
||||
propertyGrid_Transform.ToolbarVisible = false;
|
||||
//
|
||||
// tabPage_Skin
|
||||
//
|
||||
resources.ApplyResources(tabPage_Skin, "tabPage_Skin");
|
||||
tabPage_Skin.BackColor = SystemColors.Control;
|
||||
tabPage_Skin.Controls.Add(propertyGrid_Skin);
|
||||
tabPage_Skin.Name = "tabPage_Skin";
|
||||
//
|
||||
// propertyGrid_Skin
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Skin, "propertyGrid_Skin");
|
||||
propertyGrid_Skin.ContextMenuStrip = contextMenuStrip_Skin;
|
||||
propertyGrid_Skin.Name = "propertyGrid_Skin";
|
||||
propertyGrid_Skin.PropertySort = PropertySort.NoSort;
|
||||
propertyGrid_Skin.ToolbarVisible = false;
|
||||
//
|
||||
// contextMenuStrip_Skin
|
||||
//
|
||||
resources.ApplyResources(contextMenuStrip_Skin, "contextMenuStrip_Skin");
|
||||
contextMenuStrip_Skin.ImageScalingSize = new Size(24, 24);
|
||||
contextMenuStrip_Skin.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_ReloadSkins });
|
||||
contextMenuStrip_Skin.Name = "contextMenuStrip1";
|
||||
//
|
||||
// toolStripMenuItem_ReloadSkins
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_ReloadSkins, "toolStripMenuItem_ReloadSkins");
|
||||
toolStripMenuItem_ReloadSkins.Name = "toolStripMenuItem_ReloadSkins";
|
||||
toolStripMenuItem_ReloadSkins.Click += toolStripMenuItem_ReloadSkins_Click;
|
||||
//
|
||||
// tabPage_Slot
|
||||
//
|
||||
resources.ApplyResources(tabPage_Slot, "tabPage_Slot");
|
||||
tabPage_Slot.BackColor = SystemColors.Control;
|
||||
tabPage_Slot.Controls.Add(propertyGrid_Slot);
|
||||
tabPage_Slot.Name = "tabPage_Slot";
|
||||
//
|
||||
// propertyGrid_Slot
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Slot, "propertyGrid_Slot");
|
||||
propertyGrid_Slot.Name = "propertyGrid_Slot";
|
||||
propertyGrid_Slot.PropertySort = PropertySort.Alphabetical;
|
||||
propertyGrid_Slot.ToolbarVisible = false;
|
||||
//
|
||||
// tabPage_Animation
|
||||
//
|
||||
resources.ApplyResources(tabPage_Animation, "tabPage_Animation");
|
||||
tabPage_Animation.BackColor = SystemColors.Control;
|
||||
tabPage_Animation.Controls.Add(propertyGrid_Animation);
|
||||
tabPage_Animation.Name = "tabPage_Animation";
|
||||
//
|
||||
// propertyGrid_Animation
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Animation, "propertyGrid_Animation");
|
||||
propertyGrid_Animation.ContextMenuStrip = contextMenuStrip_Animation;
|
||||
propertyGrid_Animation.Name = "propertyGrid_Animation";
|
||||
propertyGrid_Animation.PropertySort = PropertySort.NoSort;
|
||||
propertyGrid_Animation.ToolbarVisible = false;
|
||||
//
|
||||
// contextMenuStrip_Animation
|
||||
//
|
||||
resources.ApplyResources(contextMenuStrip_Animation, "contextMenuStrip_Animation");
|
||||
contextMenuStrip_Animation.ImageScalingSize = new Size(24, 24);
|
||||
contextMenuStrip_Animation.Items.AddRange(new ToolStripItem[] { toolStripMenuItem_AddAnimation, toolStripMenuItem_RemoveAnimation });
|
||||
contextMenuStrip_Animation.Name = "contextMenuStrip1";
|
||||
contextMenuStrip_Animation.Opening += contextMenuStrip_Animation_Opening;
|
||||
//
|
||||
// toolStripMenuItem_AddAnimation
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_AddAnimation, "toolStripMenuItem_AddAnimation");
|
||||
toolStripMenuItem_AddAnimation.Name = "toolStripMenuItem_AddAnimation";
|
||||
toolStripMenuItem_AddAnimation.Click += toolStripMenuItem_AddAnimation_Click;
|
||||
//
|
||||
// toolStripMenuItem_RemoveAnimation
|
||||
//
|
||||
resources.ApplyResources(toolStripMenuItem_RemoveAnimation, "toolStripMenuItem_RemoveAnimation");
|
||||
toolStripMenuItem_RemoveAnimation.Name = "toolStripMenuItem_RemoveAnimation";
|
||||
toolStripMenuItem_RemoveAnimation.Click += toolStripMenuItem_RemoveAnimation_Click;
|
||||
//
|
||||
// tabPage_Debug
|
||||
//
|
||||
resources.ApplyResources(tabPage_Debug, "tabPage_Debug");
|
||||
tabPage_Debug.BackColor = SystemColors.Control;
|
||||
tabPage_Debug.Controls.Add(propertyGrid_Debug);
|
||||
tabPage_Debug.Name = "tabPage_Debug";
|
||||
//
|
||||
// propertyGrid_Debug
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Debug, "propertyGrid_Debug");
|
||||
propertyGrid_Debug.Name = "propertyGrid_Debug";
|
||||
propertyGrid_Debug.PropertySort = PropertySort.NoSort;
|
||||
propertyGrid_Debug.ToolbarVisible = false;
|
||||
//
|
||||
// SpineViewPropertyGrid
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(tabControl);
|
||||
Name = "SpineViewPropertyGrid";
|
||||
tabControl.ResumeLayout(false);
|
||||
tabPage_BaseInfo.ResumeLayout(false);
|
||||
tabPage_Render.ResumeLayout(false);
|
||||
tabPage_Transform.ResumeLayout(false);
|
||||
tabPage_Skin.ResumeLayout(false);
|
||||
contextMenuStrip_Skin.ResumeLayout(false);
|
||||
tabPage_Slot.ResumeLayout(false);
|
||||
tabPage_Animation.ResumeLayout(false);
|
||||
contextMenuStrip_Animation.ResumeLayout(false);
|
||||
tabPage_Debug.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private TabControl tabControl;
|
||||
private TabPage tabPage_BaseInfo;
|
||||
private TabPage tabPage_Render;
|
||||
private TabPage tabPage_Transform;
|
||||
private TabPage tabPage_Skin;
|
||||
private TabPage tabPage_Animation;
|
||||
private PropertyGrid propertyGrid_BaseInfo;
|
||||
private PropertyGrid propertyGrid_Render;
|
||||
private PropertyGrid propertyGrid_Transform;
|
||||
private PropertyGrid propertyGrid_Skin;
|
||||
private PropertyGrid propertyGrid_Animation;
|
||||
private ContextMenuStrip contextMenuStrip_Skin;
|
||||
private ContextMenuStrip contextMenuStrip_Animation;
|
||||
private ToolStripMenuItem toolStripMenuItem_ReloadSkins;
|
||||
private ToolStripMenuItem toolStripMenuItem_AddAnimation;
|
||||
private ToolStripMenuItem toolStripMenuItem_RemoveAnimation;
|
||||
private TabPage tabPage_Debug;
|
||||
private PropertyGrid propertyGrid_Debug;
|
||||
private TabPage tabPage_Slot;
|
||||
private PropertyGrid propertyGrid_Slot;
|
||||
}
|
||||
}
|
||||
107
SpineViewer/Controls/SpineViewPropertyGrid.cs
Normal file
107
SpineViewer/Controls/SpineViewPropertyGrid.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using SpineViewer.Utils;
|
||||
using SpineViewer.Spine.SpineView;
|
||||
|
||||
namespace SpineViewer.Controls
|
||||
{
|
||||
public partial class SpineViewPropertyGrid : UserControl
|
||||
{
|
||||
public SpineViewPropertyGrid()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置选中的对象列表, 可以赋值 null 来清空选中, 行为与 PropertyGrid.SelectedObjects 类似
|
||||
/// </summary>
|
||||
public SpineObjectProperty[] SelectedSpines
|
||||
{
|
||||
get => selectedSpines ?? [];
|
||||
set
|
||||
{
|
||||
if (value is null || value.Length <= 0)
|
||||
{
|
||||
selectedSpines = null;
|
||||
propertyGrid_BaseInfo.SelectedObject = null;
|
||||
propertyGrid_Render.SelectedObject = null;
|
||||
propertyGrid_Transform.SelectedObject = null;
|
||||
propertyGrid_Skin.SelectedObject = null;
|
||||
propertyGrid_Slot.SelectedObject = null;
|
||||
propertyGrid_Animation.SelectedObject = null;
|
||||
propertyGrid_Debug.SelectedObject = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedSpines = value;
|
||||
propertyGrid_BaseInfo.SelectedObjects = value.Select(e => e.BaseInfo).ToArray();
|
||||
propertyGrid_Render.SelectedObjects = value.Select(e => e.Render).ToArray();
|
||||
propertyGrid_Transform.SelectedObjects = value.Select(e => e.Transform).ToArray();
|
||||
propertyGrid_Skin.SelectedObjects = value.Select(e => e.Skin).ToArray();
|
||||
propertyGrid_Slot.SelectedObjects = value.Select(e => e.Slot).ToArray();
|
||||
propertyGrid_Animation.SelectedObjects = value.Select(e => e.Animation).ToArray();
|
||||
propertyGrid_Debug.SelectedObjects = value.Select(e => e.Debug).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
private SpineObjectProperty[]? selectedSpines = null;
|
||||
|
||||
private void contextMenuStrip_Animation_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
if (selectedSpines?.Length == 1)
|
||||
{
|
||||
toolStripMenuItem_AddAnimation.Enabled = true;
|
||||
toolStripMenuItem_RemoveAnimation.Enabled = propertyGrid_Animation.SelectedGridItem.Value is TrackAnimationProperty;
|
||||
}
|
||||
else
|
||||
{
|
||||
toolStripMenuItem_AddAnimation.Enabled = false;
|
||||
toolStripMenuItem_RemoveAnimation.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ReloadSkins_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach (var sp in selectedSpines)
|
||||
sp.Spine.ReloadSkins();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_AddAnimation_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (selectedSpines?.Length != 1) return;
|
||||
|
||||
var spine = selectedSpines[0].Animation.Spine;
|
||||
spine.SetAnimation(spine.GetTrackIndices().Max() + 1, spine.AnimationNames[0]);
|
||||
propertyGrid_Animation.Refresh();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_RemoveAnimation_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (selectedSpines?.Length != 1) return;
|
||||
|
||||
if (propertyGrid_Animation.SelectedGridItem.Value is TrackAnimationProperty wrapper)
|
||||
{
|
||||
selectedSpines[0].Animation.Spine.ClearTrack(wrapper.Index);
|
||||
propertyGrid_Animation.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Refresh()
|
||||
{
|
||||
base.Refresh();
|
||||
propertyGrid_BaseInfo.Refresh();
|
||||
propertyGrid_Render.Refresh();
|
||||
propertyGrid_Transform.Refresh();
|
||||
propertyGrid_Skin.Refresh();
|
||||
propertyGrid_Animation.Refresh();
|
||||
propertyGrid_Debug.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
164
SpineViewer/Controls/SpineViewPropertyGrid.en.resx
Normal file
164
SpineViewer/Controls/SpineViewPropertyGrid.en.resx
Normal file
@@ -0,0 +1,164 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="tabPage_Animation.Text" xml:space="preserve">
|
||||
<value>Animation</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAnimation.Text" xml:space="preserve">
|
||||
<value>Remove</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Text" xml:space="preserve">
|
||||
<value>Render</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.Text" xml:space="preserve">
|
||||
<value>Slot</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Text" xml:space="preserve">
|
||||
<value>Skin</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="tabPage_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 330</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Text" xml:space="preserve">
|
||||
<value>Transform</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 330</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Text" xml:space="preserve">
|
||||
<value>Debug</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ReloadSkins.Text" xml:space="preserve">
|
||||
<value>Reload skin</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 330</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="toolStripMenuItem_RemoveAnimation.Size" type="System.Resources.ResXNullRef, System.Windows.Forms">
|
||||
<value />
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 330</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Text" xml:space="preserve">
|
||||
<value>Basic Information</value>
|
||||
</data>
|
||||
</root>
|
||||
637
SpineViewer/Controls/SpineViewPropertyGrid.resx
Normal file
637
SpineViewer/Controls/SpineViewPropertyGrid.resx
Normal file
@@ -0,0 +1,637 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="propertyGrid_Slot.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="tabControl.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Animation.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip_Skin.Name" xml:space="preserve">
|
||||
<value>contextMenuStrip_Skin</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Animation.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Animation</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="tabPage_Slot.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip_Skin.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>170, 28</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Skin.Name" xml:space="preserve">
|
||||
<value>tabPage_Skin</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Debug.Name" xml:space="preserve">
|
||||
<value>tabPage_Debug</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_BaseInfo.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Transform.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tabPage_BaseInfo.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Render.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabControl.ItemSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>90, 35</value>
|
||||
</data>
|
||||
<data name="tabControl.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>271, 373</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="propertyGrid_Debug.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.Text" xml:space="preserve">
|
||||
<value>动画</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Animation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_BaseInfo.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tabControl.Name" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>tabControl.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="contextMenuStrip_Animation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>109, 52</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip_Animation.Name" xml:space="preserve">
|
||||
<value>contextMenuStrip_Animation</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_RemoveAnimation.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_RemoveAnimation</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Debug.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="$this.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>271, 373</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Debug.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Debug</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_BaseInfo.Name" xml:space="preserve">
|
||||
<value>propertyGrid_BaseInfo</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Transform.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Transform</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAnimation.Text" xml:space="preserve">
|
||||
<value>移除</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Skin.Parent" xml:space="preserve">
|
||||
<value>tabPage_Skin</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ReloadSkins.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Render.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tabControl.Alignment" type="System.Windows.Forms.TabAlignment, System.Windows.Forms">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip_Skin.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Transform.Name" xml:space="preserve">
|
||||
<value>tabPage_Transform</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Render.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Render.Name" xml:space="preserve">
|
||||
<value>tabPage_Render</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Slot.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>tabPage_BaseInfo.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Text" xml:space="preserve">
|
||||
<value>渲染</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_AddAnimation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.Text" xml:space="preserve">
|
||||
<value>插槽</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Render.Parent" xml:space="preserve">
|
||||
<value>tabPage_Render</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Text" xml:space="preserve">
|
||||
<value>皮肤</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Skin.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Slot.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="tabPage_Render.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tabControl.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Slot.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabControl.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name=">>tabControl.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Skin.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Debug.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Skin.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.UserControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Skin.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Text" xml:space="preserve">
|
||||
<value>变换</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Debug.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Slot.Parent" xml:space="preserve">
|
||||
<value>tabPage_Slot</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Transform.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Render.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>tabPage_BaseInfo.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddAnimation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>108, 24</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Slot.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Skin.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Animation.Name" xml:space="preserve">
|
||||
<value>tabPage_Animation</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Transform.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabControl.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_AddAnimation.Text" xml:space="preserve">
|
||||
<value>添加</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ReloadSkins.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>169, 24</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Text" xml:space="preserve">
|
||||
<value>调试</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Animation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_ReloadSkins.Text" xml:space="preserve">
|
||||
<value>重新加载皮肤</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Slot.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Slot</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tabPage_BaseInfo.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>SpineViewPropertyGrid</value>
|
||||
</data>
|
||||
<data name=">>tabControl.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabControl, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>contextMenuStrip_Animation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Slot.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="tabPage_Animation.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Debug.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Slot.Name" xml:space="preserve">
|
||||
<value>tabPage_Slot</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Animation.Parent" xml:space="preserve">
|
||||
<value>tabPage_Animation</value>
|
||||
</data>
|
||||
<data name="tabPage_Transform.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name=">>tabPage_BaseInfo.Name" xml:space="preserve">
|
||||
<value>tabPage_BaseInfo</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_BaseInfo.Parent" xml:space="preserve">
|
||||
<value>tabPage_BaseInfo</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Transform.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Skin.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_Debug.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Debug.Parent" xml:space="preserve">
|
||||
<value>tabPage_Debug</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Transform.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Slot.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabControl.Padding" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="toolStripMenuItem_RemoveAnimation.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>108, 24</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Debug.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Transform.Parent" xml:space="preserve">
|
||||
<value>tabPage_Transform</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="tabPage_Slot.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>4, 4</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_AddAnimation.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_AddAnimation</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Animation.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Render.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Render</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Debug.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_BaseInfo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Transform.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>263, 295</value>
|
||||
</data>
|
||||
<data name="tabPage_Skin.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Animation.Parent" xml:space="preserve">
|
||||
<value>tabControl</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Animation.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>tabPage_Render.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TabPage, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_ReloadSkins.Name" xml:space="preserve">
|
||||
<value>toolStripMenuItem_ReloadSkins</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid_Skin.Name" xml:space="preserve">
|
||||
<value>propertyGrid_Skin</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name="propertyGrid_Render.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>toolStripMenuItem_RemoveAnimation.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tabPage_BaseInfo.Text" xml:space="preserve">
|
||||
<value>基本信息</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip_Skin.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>29, 26</value>
|
||||
</metadata>
|
||||
<metadata name="contextMenuStrip_Animation.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>318, 25</value>
|
||||
</metadata>
|
||||
</root>
|
||||
194
SpineViewer/Dialogs/AboutDialog.Designer.cs
generated
194
SpineViewer/Dialogs/AboutDialog.Designer.cs
generated
@@ -19,130 +19,82 @@
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows 窗体设计器生成的代码
|
||||
#region Windows 窗体设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutDialog));
|
||||
tableLayoutPanel_About = new TableLayoutPanel();
|
||||
label3 = new Label();
|
||||
label1 = new Label();
|
||||
label_Version = new Label();
|
||||
linkLabel_RepoUrl = new LinkLabel();
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel_About.SuspendLayout();
|
||||
panel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel_About
|
||||
//
|
||||
tableLayoutPanel_About.BackColor = Color.Transparent;
|
||||
tableLayoutPanel_About.ColumnCount = 2;
|
||||
tableLayoutPanel_About.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 28.5714283F));
|
||||
tableLayoutPanel_About.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 71.42857F));
|
||||
tableLayoutPanel_About.Controls.Add(label3, 0, 1);
|
||||
tableLayoutPanel_About.Controls.Add(label1, 0, 0);
|
||||
tableLayoutPanel_About.Controls.Add(label_Version, 1, 0);
|
||||
tableLayoutPanel_About.Controls.Add(linkLabel_RepoUrl, 1, 1);
|
||||
tableLayoutPanel_About.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel_About.Location = new Point(50, 15);
|
||||
tableLayoutPanel_About.Margin = new Padding(0);
|
||||
tableLayoutPanel_About.Name = "tableLayoutPanel_About";
|
||||
tableLayoutPanel_About.RowCount = 3;
|
||||
tableLayoutPanel_About.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel_About.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel_About.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel_About.Size = new Size(604, 254);
|
||||
tableLayoutPanel_About.TabIndex = 1;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.AutoSize = true;
|
||||
label3.Dock = DockStyle.Fill;
|
||||
label3.Location = new Point(3, 54);
|
||||
label3.Margin = new Padding(3, 10, 3, 10);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new Size(166, 24);
|
||||
label3.TabIndex = 2;
|
||||
label3.Text = "项目地址:";
|
||||
label3.TextAlign = ContentAlignment.MiddleRight;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Dock = DockStyle.Fill;
|
||||
label1.Location = new Point(3, 10);
|
||||
label1.Margin = new Padding(3, 10, 3, 10);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(166, 24);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "程序版本:";
|
||||
label1.TextAlign = ContentAlignment.MiddleRight;
|
||||
//
|
||||
// label_Version
|
||||
//
|
||||
label_Version.Anchor = AnchorStyles.Left;
|
||||
label_Version.AutoSize = true;
|
||||
label_Version.Location = new Point(175, 10);
|
||||
label_Version.Name = "label_Version";
|
||||
label_Version.Size = new Size(61, 24);
|
||||
label_Version.TabIndex = 1;
|
||||
label_Version.Text = "vX.Y.Z";
|
||||
label_Version.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// linkLabel_RepoUrl
|
||||
//
|
||||
linkLabel_RepoUrl.Anchor = AnchorStyles.Left;
|
||||
linkLabel_RepoUrl.AutoSize = true;
|
||||
linkLabel_RepoUrl.Location = new Point(175, 54);
|
||||
linkLabel_RepoUrl.Name = "linkLabel_RepoUrl";
|
||||
linkLabel_RepoUrl.Size = new Size(356, 24);
|
||||
linkLabel_RepoUrl.TabIndex = 3;
|
||||
linkLabel_RepoUrl.TabStop = true;
|
||||
linkLabel_RepoUrl.Text = "https://github.com/ww-rm/SpineViewer";
|
||||
linkLabel_RepoUrl.LinkClicked += linkLabel_RepoUrl_LinkClicked;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.BackgroundImageLayout = ImageLayout.Center;
|
||||
panel1.Controls.Add(tableLayoutPanel_About);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(16, 17);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(50, 15, 50, 10);
|
||||
panel1.Size = new Size(704, 279);
|
||||
panel1.TabIndex = 2;
|
||||
//
|
||||
// AboutDialog
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(736, 313);
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
Margin = new Padding(6);
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "AboutDialog";
|
||||
Padding = new Padding(16, 17, 16, 17);
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterParent;
|
||||
Text = "关于 SpineViewer";
|
||||
tableLayoutPanel_About.ResumeLayout(false);
|
||||
tableLayoutPanel_About.PerformLayout();
|
||||
panel1.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutDialog));
|
||||
tableLayoutPanel_About = new TableLayoutPanel();
|
||||
label3 = new Label();
|
||||
label1 = new Label();
|
||||
label_Version = new Label();
|
||||
linkLabel_RepoUrl = new LinkLabel();
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel_About.SuspendLayout();
|
||||
panel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel_About
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel_About, "tableLayoutPanel_About");
|
||||
tableLayoutPanel_About.BackColor = Color.Transparent;
|
||||
tableLayoutPanel_About.Controls.Add(label3, 0, 1);
|
||||
tableLayoutPanel_About.Controls.Add(label1, 0, 0);
|
||||
tableLayoutPanel_About.Controls.Add(label_Version, 1, 0);
|
||||
tableLayoutPanel_About.Controls.Add(linkLabel_RepoUrl, 1, 1);
|
||||
tableLayoutPanel_About.Name = "tableLayoutPanel_About";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(label3, "label3");
|
||||
label3.Name = "label3";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
resources.ApplyResources(label1, "label1");
|
||||
label1.Name = "label1";
|
||||
//
|
||||
// label_Version
|
||||
//
|
||||
resources.ApplyResources(label_Version, "label_Version");
|
||||
label_Version.Name = "label_Version";
|
||||
//
|
||||
// linkLabel_RepoUrl
|
||||
//
|
||||
resources.ApplyResources(linkLabel_RepoUrl, "linkLabel_RepoUrl");
|
||||
linkLabel_RepoUrl.Name = "linkLabel_RepoUrl";
|
||||
linkLabel_RepoUrl.TabStop = true;
|
||||
linkLabel_RepoUrl.LinkClicked += linkLabel_RepoUrl_LinkClicked;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel_About);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// AboutDialog
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "AboutDialog";
|
||||
ShowInTaskbar = false;
|
||||
tableLayoutPanel_About.ResumeLayout(false);
|
||||
tableLayoutPanel_About.PerformLayout();
|
||||
panel1.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
private TableLayoutPanel tableLayoutPanel_About;
|
||||
private TableLayoutPanel tableLayoutPanel_About;
|
||||
private Label label3;
|
||||
private Label label1;
|
||||
private Label label_Version;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
@@ -15,15 +16,19 @@ namespace SpineViewer.Dialogs
|
||||
public AboutDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.label_Version.Text = $"v{InformationalVersion}";
|
||||
Text = $"{Properties.Resources.about} {ProgramName}";
|
||||
label_Version.Text = $"v{InformationalVersion}";
|
||||
}
|
||||
|
||||
public string ProgramName => Process.GetCurrentProcess().ProcessName;
|
||||
|
||||
public string InformationalVersion
|
||||
=> Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
|
||||
public string ProgramUrl
|
||||
{
|
||||
get
|
||||
{
|
||||
return Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
||||
}
|
||||
get => linkLabel_RepoUrl.Text;
|
||||
set => linkLabel_RepoUrl.Text = value;
|
||||
}
|
||||
|
||||
private void linkLabel_RepoUrl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
@@ -36,7 +41,7 @@ namespace SpineViewer.Dialogs
|
||||
else
|
||||
{
|
||||
Clipboard.SetText(url);
|
||||
MessageBox.Show(this, "链接已复制到剪贴板,请前往浏览器进行访问", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessagePopup.Info(Properties.Resources.notifyCopyGithubLink, Properties.Resources.msgBoxInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,9 +117,12 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="folderBrowserDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>Github link:</value>
|
||||
</data>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>Version:</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
@@ -3267,4 +3270,7 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>About SpineViewer</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,7 +117,82 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="label_Version.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name=">>label1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name="label3.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="label_Version.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="label_Version.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>48, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="label_Version.Text" xml:space="preserve">
|
||||
<value>vX.Y.Z</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>linkLabel_RepoUrl.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.LinkLabel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="linkLabel_RepoUrl.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name="label3.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleRight</value>
|
||||
</data>
|
||||
<data name="label3.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 8, 2, 8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.RowCount" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 8</value>
|
||||
</data>
|
||||
<data name=">>label3.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name=">>linkLabel_RepoUrl.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>36, 12</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>127, 44</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>AboutDialog</value>
|
||||
</data>
|
||||
<data name=">>label3.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>关于 SpineViewer</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3264,4 +3339,169 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="label1.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleRight</value>
|
||||
</data>
|
||||
<data name=">>label3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="label_Version.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleLeft</value>
|
||||
</data>
|
||||
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>121, 20</value>
|
||||
</data>
|
||||
<data name=">>panel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label_Version.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name=">>label1.Name" xml:space="preserve">
|
||||
<value>label1</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.Text" xml:space="preserve">
|
||||
<value>https://github.com/ww-rm/SpineViewer</value>
|
||||
</data>
|
||||
<data name=">>label3.Name" xml:space="preserve">
|
||||
<value>label3</value>
|
||||
</data>
|
||||
<data name=">>label_Version.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel_About.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>4, 5, 4, 5</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>panel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="label3.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>panel1.Name" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="label1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 8, 2, 8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label3" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label1" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label_Version" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="linkLabel_RepoUrl" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,28.571428,Percent,71.42857" /><Rows Styles="AutoSize,0,AutoSize,0,Percent,100" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>label_Version.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 44</value>
|
||||
</data>
|
||||
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>121, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>439, 213</value>
|
||||
</data>
|
||||
<data name="label_Version.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name=">>label1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel_About.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>0, 0, 0, 0</value>
|
||||
</data>
|
||||
<data name=">>label_Version.Name" xml:space="preserve">
|
||||
<value>label_Version</value>
|
||||
</data>
|
||||
<data name="linkLabel_RepoUrl.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>272, 20</value>
|
||||
</data>
|
||||
<data name=">>linkLabel_RepoUrl.Name" xml:space="preserve">
|
||||
<value>linkLabel_RepoUrl</value>
|
||||
</data>
|
||||
<data name="label_Version.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>127, 8</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 14</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel_About.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="label1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>panel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel_About.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>511, 233</value>
|
||||
</data>
|
||||
<data name="$this.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>12, 14, 12, 14</value>
|
||||
</data>
|
||||
<data name=">>linkLabel_RepoUrl.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>程序版本:</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterParent</value>
|
||||
</data>
|
||||
<data name="panel1.BackgroundImageLayout" type="System.Windows.Forms.ImageLayout, System.Windows.Forms">
|
||||
<value>Center</value>
|
||||
</data>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>项目地址:</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel_About.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel_About</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>535, 261</value>
|
||||
</data>
|
||||
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>36, 12, 36, 8</value>
|
||||
</data>
|
||||
<data name="label_Version.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>label1.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
310
SpineViewer/Dialogs/BatchOpenSpineDialog.Designer.cs
generated
310
SpineViewer/Dialogs/BatchOpenSpineDialog.Designer.cs
generated
@@ -20,218 +20,120 @@
|
||||
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();
|
||||
listBox_FilePath = new ListBox();
|
||||
button_SelectSkel = new Button();
|
||||
label_Tip = new Label();
|
||||
openFileDialog_Skel = new OpenFileDialog();
|
||||
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(1126, 449);
|
||||
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, 3);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_Version, 1, 3);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 4);
|
||||
tableLayoutPanel1.Controls.Add(listBox_FilePath, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectSkel, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(label_Tip, 1, 1);
|
||||
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(1026, 424);
|
||||
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(996, 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(90, 307);
|
||||
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(146, 303);
|
||||
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.Bottom;
|
||||
tableLayoutPanel2.Location = new Point(3, 381);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
tableLayoutPanel2.RowCount = 1;
|
||||
tableLayoutPanel2.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel2.Size = new Size(1020, 40);
|
||||
tableLayoutPanel2.TabIndex = 11;
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
button_Ok.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
button_Ok.Location = new Point(368, 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(540, 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;
|
||||
//
|
||||
// listBox_FilePath
|
||||
//
|
||||
tableLayoutPanel1.SetColumnSpan(listBox_FilePath, 2);
|
||||
listBox_FilePath.Dock = DockStyle.Fill;
|
||||
listBox_FilePath.FormattingEnabled = true;
|
||||
listBox_FilePath.HorizontalScrollbar = true;
|
||||
listBox_FilePath.ItemHeight = 24;
|
||||
listBox_FilePath.Location = new Point(3, 97);
|
||||
listBox_FilePath.Name = "listBox_FilePath";
|
||||
listBox_FilePath.Size = new Size(1020, 200);
|
||||
listBox_FilePath.TabIndex = 2;
|
||||
//
|
||||
// button_SelectSkel
|
||||
//
|
||||
button_SelectSkel.Anchor = AnchorStyles.None;
|
||||
button_SelectSkel.Location = new Point(3, 57);
|
||||
button_SelectSkel.Name = "button_SelectSkel";
|
||||
button_SelectSkel.Size = new Size(137, 34);
|
||||
button_SelectSkel.TabIndex = 1;
|
||||
button_SelectSkel.Text = "选择文件...";
|
||||
button_SelectSkel.UseVisualStyleBackColor = true;
|
||||
button_SelectSkel.Click += button_SelectSkel_Click;
|
||||
//
|
||||
// label_Tip
|
||||
//
|
||||
label_Tip.AutoSize = true;
|
||||
label_Tip.Dock = DockStyle.Fill;
|
||||
label_Tip.Location = new Point(146, 54);
|
||||
label_Tip.Name = "label_Tip";
|
||||
label_Tip.Size = new Size(877, 40);
|
||||
label_Tip.TabIndex = 0;
|
||||
label_Tip.Text = "已选择 0 个文件";
|
||||
label_Tip.TextAlign = ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// openFileDialog_Skel
|
||||
//
|
||||
openFileDialog_Skel.AddExtension = false;
|
||||
openFileDialog_Skel.AddToRecent = false;
|
||||
openFileDialog_Skel.Filter = "skel 文件 (*.skel; *.json)|*.skel;*.json|所有文件 (*.*)|*.*";
|
||||
openFileDialog_Skel.Multiselect = true;
|
||||
//
|
||||
// BatchOpenSpineDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
ClientSize = new Size(1126, 449);
|
||||
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 Label label_Tip;
|
||||
private ListBox listBox_FilePath;
|
||||
private Button button_SelectSkel;
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
private Button button_Cancel;
|
||||
private Label label3;
|
||||
private ComboBox comboBox_Version;
|
||||
private OpenFileDialog openFileDialog_Skel;
|
||||
private Label label4;
|
||||
private Controls.SkelFileListBox skelFileListBox;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using SpineViewer.Spine;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -13,49 +14,48 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class BatchOpenSpineDialog : Form
|
||||
{
|
||||
public string[] SkelPaths { get; private set; }
|
||||
public Spine.Version Version { get; private set; }
|
||||
/// <summary>
|
||||
/// 对话框结果, 取消时为 null
|
||||
/// </summary>
|
||||
public BatchOpenSpineDialogResult Result { get; private set; }
|
||||
|
||||
public BatchOpenSpineDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
comboBox_Version.DataSource = VersionHelper.Versions.ToList();
|
||||
comboBox_Version.DataSource = SpineUtils.Names.ToList();
|
||||
comboBox_Version.DisplayMember = "Value";
|
||||
comboBox_Version.ValueMember = "Key";
|
||||
comboBox_Version.SelectedValue = Spine.Version.V38;
|
||||
}
|
||||
|
||||
private void button_SelectSkel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (openFileDialog_Skel.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
listBox_FilePath.Items.Clear();
|
||||
foreach (var p in openFileDialog_Skel.FileNames)
|
||||
listBox_FilePath.Items.Add(Path.GetFullPath(p));
|
||||
label_Tip.Text = $"已选择 {listBox_FilePath.Items.Count} 个文件";
|
||||
}
|
||||
comboBox_Version.SelectedValue = SpineVersion.Auto;
|
||||
}
|
||||
|
||||
private void button_Ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (listBox_FilePath.Items.Count <= 0)
|
||||
var version = (SpineVersion)comboBox_Version.SelectedValue;
|
||||
|
||||
var items = skelFileListBox.Items;
|
||||
|
||||
if (items.Count <= 0)
|
||||
{
|
||||
MessageBox.Show("未选择任何文件", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessagePopup.Info("未选择任何文件", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string p in listBox_FilePath.Items)
|
||||
foreach (string p in items)
|
||||
{
|
||||
if (!File.Exists(p))
|
||||
{
|
||||
MessageBox.Show($"{p}", "skel文件不存在", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessagePopup.Info($"{p}", Properties.Resources.skelNotExist);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SkelPaths = listBox_FilePath.Items.Cast<string>().ToArray();
|
||||
Version = (Spine.Version)comboBox_Version.SelectedValue;
|
||||
if (version != SpineVersion.Auto && !Spine.SpineObject.HasImplementation(version))
|
||||
{
|
||||
MessagePopup.Info($"{version.GetName()} 版本尚未实现(咕咕咕~)", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
Result = new(version, items.Cast<string>().ToArray());
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
@@ -64,4 +64,20 @@ namespace SpineViewer.Dialogs
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量打开对话框结果
|
||||
/// </summary>
|
||||
public class BatchOpenSpineDialogResult(SpineVersion version, string[] skelPaths)
|
||||
{
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
public SpineVersion Version => version;
|
||||
|
||||
/// <summary>
|
||||
/// 路径列表
|
||||
/// </summary>
|
||||
public string[] SkelPaths => skelPaths;
|
||||
}
|
||||
}
|
||||
|
||||
3297
SpineViewer/Dialogs/BatchOpenSpineDialog.en.resx
Normal file
3297
SpineViewer/Dialogs/BatchOpenSpineDialog.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -117,10 +117,103 @@
|
||||
<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.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="skelFileListBox.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>684, 234</value>
|
||||
</data>
|
||||
<data name=">>panel.Name" xml:space="preserve">
|
||||
<value>panel</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>133, 28</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>682, 32</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Ok.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Right</value>
|
||||
</data>
|
||||
<data name="label4.Text" xml:space="preserve">
|
||||
<value>说明:批量导入只需要选择skel文件,atlas文件需要在同目录下并且与skel文件名相同</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>1, 46</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>label4.Name" xml:space="preserve">
|
||||
<value>label4</value>
|
||||
</data>
|
||||
<data name=">>panel.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 339</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="label3.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="panel.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>36, 12, 36, 8</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>22, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Ok.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name=">>label3.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>label4.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>panel.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="button_Ok.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 22, 2</value>
|
||||
</data>
|
||||
<data name="panel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="panel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3267,4 +3360,226 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="label4.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>11, 12</value>
|
||||
</data>
|
||||
<data name=">>label3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>1, 2, 1, 2</value>
|
||||
</data>
|
||||
<data name="label4.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleCenter</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Name" xml:space="preserve">
|
||||
<value>button_Ok</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>批量打开骨骼</value>
|
||||
</data>
|
||||
<data name=">>label4.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="button_Ok.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>238, 2</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>label3.Name" xml:space="preserve">
|
||||
<value>label3</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>686, 373</value>
|
||||
</data>
|
||||
<data name=">>label4.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Ok.Text" xml:space="preserve">
|
||||
<value>确认</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Name" xml:space="preserve">
|
||||
<value>button_Cancel</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>363, 2</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>BatchOpenSpineDialog</value>
|
||||
</data>
|
||||
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 288</value>
|
||||
</data>
|
||||
<data name="panel.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="label4.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label3.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="label4.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 12, 11, 12</value>
|
||||
</data>
|
||||
<data name="label4.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Name" xml:space="preserve">
|
||||
<value>skelFileListBox</value>
|
||||
</data>
|
||||
<data name="panel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>664, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 25, 2, 2</value>
|
||||
</data>
|
||||
<data name="label3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>758, 393</value>
|
||||
</data>
|
||||
<data name="label4.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>42, 20</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>48, 284</value>
|
||||
</data>
|
||||
<data name="button_Cancel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Name" xml:space="preserve">
|
||||
<value>comboBox_Version</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="panel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>758, 393</value>
|
||||
</data>
|
||||
<data name="button_Ok.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="skelFileListBox.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>15</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label4" Row="0" RowSpan="1" Column="0" ColumnSpan="4" /><Control Name="label3" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboBox_Version" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="tableLayoutPanel2" Row="3" RowSpan="1" Column="0" ColumnSpan="4" /><Control Name="skelFileListBox" Row="1" RowSpan="1" Column="0" ColumnSpan="2" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,Percent,100,AutoSize,0,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.RowCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>版本:</value>
|
||||
</data>
|
||||
<data name=">>panel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel</value>
|
||||
</data>
|
||||
<data name=">>skelFileListBox.Type" xml:space="preserve">
|
||||
<value>SpineViewer.Controls.SkelFileListBox, SpineViewer, Culture=neutral, PublicKeyToken=null</value>
|
||||
</data>
|
||||
<data name=">>label3.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>36, 12</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
241
SpineViewer/Dialogs/ConvertFileFormatDialog.Designer.cs
generated
Normal file
241
SpineViewer/Dialogs/ConvertFileFormatDialog.Designer.cs
generated
Normal file
@@ -0,0 +1,241 @@
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
partial class ConvertFileFormatDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConvertFileFormatDialog));
|
||||
panel = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label5 = new Label();
|
||||
comboBox_TargetVersion = new ComboBox();
|
||||
flowLayoutPanel_TargetFormat = new FlowLayoutPanel();
|
||||
radioButton_BinaryTarget = new RadioButton();
|
||||
radioButton_JsonTarget = new RadioButton();
|
||||
label1 = new Label();
|
||||
label4 = new Label();
|
||||
label3 = new Label();
|
||||
comboBox_SourceVersion = new ComboBox();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
label2 = new Label();
|
||||
skelFileListBox = new SpineViewer.Controls.SkelFileListBox();
|
||||
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.Name = "panel";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
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, 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.Controls.Add(tableLayoutPanel3, 1, 2);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// label5
|
||||
//
|
||||
resources.ApplyResources(label5, "label5");
|
||||
label5.Name = "label5";
|
||||
//
|
||||
// comboBox_TargetVersion
|
||||
//
|
||||
resources.ApplyResources(comboBox_TargetVersion, "comboBox_TargetVersion");
|
||||
comboBox_TargetVersion.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_TargetVersion.FormattingEnabled = true;
|
||||
comboBox_TargetVersion.Name = "comboBox_TargetVersion";
|
||||
comboBox_TargetVersion.Sorted = true;
|
||||
//
|
||||
// flowLayoutPanel_TargetFormat
|
||||
//
|
||||
resources.ApplyResources(flowLayoutPanel_TargetFormat, "flowLayoutPanel_TargetFormat");
|
||||
flowLayoutPanel_TargetFormat.Controls.Add(radioButton_BinaryTarget);
|
||||
flowLayoutPanel_TargetFormat.Controls.Add(radioButton_JsonTarget);
|
||||
flowLayoutPanel_TargetFormat.Name = "flowLayoutPanel_TargetFormat";
|
||||
//
|
||||
// radioButton_BinaryTarget
|
||||
//
|
||||
resources.ApplyResources(radioButton_BinaryTarget, "radioButton_BinaryTarget");
|
||||
radioButton_BinaryTarget.Name = "radioButton_BinaryTarget";
|
||||
radioButton_BinaryTarget.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// radioButton_JsonTarget
|
||||
//
|
||||
resources.ApplyResources(radioButton_JsonTarget, "radioButton_JsonTarget");
|
||||
radioButton_JsonTarget.Checked = true;
|
||||
radioButton_JsonTarget.Name = "radioButton_JsonTarget";
|
||||
radioButton_JsonTarget.TabStop = true;
|
||||
radioButton_JsonTarget.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
resources.ApplyResources(label1, "label1");
|
||||
label1.Name = "label1";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
resources.ApplyResources(label4, "label4");
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Name = "label4";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(label3, "label3");
|
||||
label3.Name = "label3";
|
||||
//
|
||||
// comboBox_SourceVersion
|
||||
//
|
||||
resources.ApplyResources(comboBox_SourceVersion, "comboBox_SourceVersion");
|
||||
comboBox_SourceVersion.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_SourceVersion.FormattingEnabled = true;
|
||||
comboBox_SourceVersion.Name = "comboBox_SourceVersion";
|
||||
comboBox_SourceVersion.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;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
resources.ApplyResources(label2, "label2");
|
||||
label2.Name = "label2";
|
||||
//
|
||||
// skelFileListBox
|
||||
//
|
||||
resources.ApplyResources(skelFileListBox, "skelFileListBox");
|
||||
tableLayoutPanel1.SetColumnSpan(skelFileListBox, 2);
|
||||
skelFileListBox.Name = "skelFileListBox";
|
||||
//
|
||||
// tableLayoutPanel3
|
||||
//
|
||||
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;
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
Controls.Add(panel);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ConvertFileFormatDialog";
|
||||
ShowInTaskbar = false;
|
||||
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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Label label4;
|
||||
private Label label3;
|
||||
private ComboBox comboBox_SourceVersion;
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
private Button button_Cancel;
|
||||
private Label label1;
|
||||
private Label label2;
|
||||
private FlowLayoutPanel flowLayoutPanel_TargetFormat;
|
||||
private RadioButton radioButton_BinaryTarget;
|
||||
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;
|
||||
}
|
||||
}
|
||||
157
SpineViewer/Dialogs/ConvertFileFormatDialog.cs
Normal file
157
SpineViewer/Dialogs/ConvertFileFormatDialog.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
using NLog;
|
||||
using SpineViewer.Spine;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ConvertFileFormatDialog : Form
|
||||
{
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 对话框结果, 取消时为 null
|
||||
/// </summary>
|
||||
public ConvertFileFormatDialogResult Result { get; private set; }
|
||||
|
||||
public ConvertFileFormatDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
comboBox_SourceVersion.DataSource = SpineUtils.Names.ToList();
|
||||
comboBox_SourceVersion.DisplayMember = "Value";
|
||||
comboBox_SourceVersion.ValueMember = "Key";
|
||||
comboBox_SourceVersion.SelectedValue = SpineVersion.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 = 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 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)
|
||||
{
|
||||
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))
|
||||
{
|
||||
MessagePopup.Info($"{p}", Properties.Resources.skelNotExist);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceVersion != SpineVersion.Auto && !SkeletonConverter.HasImplementation(sourceVersion))
|
||||
{
|
||||
MessagePopup.Info($"{sourceVersion.GetName()} 版本尚未实现(咕咕咕~)", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SkeletonConverter.HasImplementation(targetVersion))
|
||||
{
|
||||
MessagePopup.Info($"{targetVersion.GetName()} 版本尚未实现(咕咕咕~)", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
Result = new(outputDir, items.Cast<string>().ToArray(), sourceVersion, targetVersion, jsonTarget);
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void button_Cancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 文件格式转换对话框结果包装类
|
||||
/// </summary>
|
||||
public class ConvertFileFormatDialogResult(string? outputDir, string[] skelPaths, SpineVersion sourceVersion, SpineVersion targetVersion, bool jsonTarget)
|
||||
{
|
||||
/// <summary>
|
||||
/// 输出文件夹, 如果为空, 则将转换后的文件转换到各自的文件夹下
|
||||
/// </summary>
|
||||
public string? OutputDir => outputDir;
|
||||
|
||||
/// <summary>
|
||||
/// 骨骼文件路径列表
|
||||
/// </summary>
|
||||
public string[] SkelPaths => skelPaths;
|
||||
|
||||
/// <summary>
|
||||
/// 源版本
|
||||
/// </summary>
|
||||
public SpineVersion SourceVersion => sourceVersion;
|
||||
|
||||
/// <summary>
|
||||
/// 目标版本
|
||||
/// </summary>
|
||||
public SpineVersion TargetVersion => targetVersion;
|
||||
|
||||
/// <summary>
|
||||
/// 目标格式是否为 Json
|
||||
/// </summary>
|
||||
public bool JsonTarget => jsonTarget;
|
||||
}
|
||||
}
|
||||
3351
SpineViewer/Dialogs/ConvertFileFormatDialog.en.resx
Normal file
3351
SpineViewer/Dialogs/ConvertFileFormatDialog.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
3903
SpineViewer/Dialogs/ConvertFileFormatDialog.resx
Normal file
3903
SpineViewer/Dialogs/ConvertFileFormatDialog.resx
Normal file
File diff suppressed because it is too large
Load Diff
146
SpineViewer/Dialogs/DiagnosticsDialog.Designer.cs
generated
146
SpineViewer/Dialogs/DiagnosticsDialog.Designer.cs
generated
@@ -20,96 +20,68 @@
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DiagnosticsDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
button_Copy = new Button();
|
||||
propertyGrid = new PropertyGrid();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(0, 0);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(50, 15, 50, 10);
|
||||
panel1.Size = new Size(901, 452);
|
||||
panel1.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.AutoSize = true;
|
||||
tableLayoutPanel1.ColumnCount = 1;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.Controls.Add(button_Copy, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(propertyGrid, 0, 0);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(50, 15);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 2;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(801, 427);
|
||||
tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// button_Copy
|
||||
//
|
||||
button_Copy.Anchor = AnchorStyles.None;
|
||||
button_Copy.AutoSize = true;
|
||||
button_Copy.Location = new Point(326, 390);
|
||||
button_Copy.Margin = new Padding(3, 10, 3, 3);
|
||||
button_Copy.Name = "button_Copy";
|
||||
button_Copy.Padding = new Padding(10, 0, 10, 0);
|
||||
button_Copy.Size = new Size(148, 34);
|
||||
button_Copy.TabIndex = 12;
|
||||
button_Copy.Text = "复制到剪贴板";
|
||||
button_Copy.UseVisualStyleBackColor = true;
|
||||
button_Copy.Click += button_Copy_Click;
|
||||
//
|
||||
// propertyGrid
|
||||
//
|
||||
propertyGrid.Dock = DockStyle.Fill;
|
||||
propertyGrid.HelpVisible = false;
|
||||
propertyGrid.Location = new Point(3, 3);
|
||||
propertyGrid.Name = "propertyGrid";
|
||||
propertyGrid.Size = new Size(795, 374);
|
||||
propertyGrid.TabIndex = 13;
|
||||
propertyGrid.ToolbarVisible = false;
|
||||
//
|
||||
// DiagnosticsDialog
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(901, 452);
|
||||
Controls.Add(panel1);
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "DiagnosticsDialog";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "诊断信息";
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DiagnosticsDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
button_Copy = new Button();
|
||||
propertyGrid = new PropertyGrid();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(button_Copy, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(propertyGrid, 0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// button_Copy
|
||||
//
|
||||
resources.ApplyResources(button_Copy, "button_Copy");
|
||||
button_Copy.Name = "button_Copy";
|
||||
button_Copy.UseVisualStyleBackColor = true;
|
||||
button_Copy.Click += button_Copy_Click;
|
||||
//
|
||||
// propertyGrid
|
||||
//
|
||||
resources.ApplyResources(propertyGrid, "propertyGrid");
|
||||
propertyGrid.Name = "propertyGrid";
|
||||
propertyGrid.ToolbarVisible = false;
|
||||
//
|
||||
// DiagnosticsDialog
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
Controls.Add(panel1);
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "DiagnosticsDialog";
|
||||
ShowInTaskbar = false;
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Button button_Copy;
|
||||
private PropertyGrid propertyGrid;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Win32;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -26,7 +27,29 @@ namespace SpineViewer.Dialogs
|
||||
|
||||
private class DiagnosticsInformation
|
||||
{
|
||||
[Category("Versions")]
|
||||
[Category("Hardware")]
|
||||
public string CPU
|
||||
{
|
||||
get => Registry.GetValue(@"HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0", "ProcessorNameString", "Unknown").ToString();
|
||||
}
|
||||
|
||||
[Category("Hardware")]
|
||||
public string Memory
|
||||
{
|
||||
get => $"{new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory / 1024f / 1024f / 1024f:F1} GB";
|
||||
}
|
||||
|
||||
[Category("Hardware")]
|
||||
public string GPU
|
||||
{
|
||||
get
|
||||
{
|
||||
var searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_VideoController");
|
||||
return string.Join("; ", searcher.Get().Cast<ManagementObject>().Select(mo => mo["Name"].ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
[Category("Software")]
|
||||
public string WindowsVersion
|
||||
{
|
||||
get
|
||||
@@ -39,54 +62,38 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
private void button_Copy_Click(object sender, EventArgs e)
|
||||
{
|
||||
var selectedObject = propertyGrid.SelectedObject as DiagnosticsInformation;
|
||||
var selectedObject = (DiagnosticsInformation)propertyGrid.SelectedObject;
|
||||
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.Show(this, "已复制", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessagePopup.Info("已复制", Properties.Resources.msgBoxInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,16 +117,16 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>187, 20</value>
|
||||
</metadata>
|
||||
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>89</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="button_Copy.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>214, 325</value>
|
||||
</data>
|
||||
<data name="button_Copy.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>155, 30</value>
|
||||
</data>
|
||||
<data name="button_Copy.Text" xml:space="preserve">
|
||||
<value>Copy to Clipboard</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3273,4 +3273,7 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Diagnostic Information</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,7 +117,36 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Copy.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>None</value>
|
||||
</data>
|
||||
<data name=">>button_Copy.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>panel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="button_Copy.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>124, 30</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="propertyGrid.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 2</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3264,4 +3293,140 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name=">>panel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>button_Copy.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Copy.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 8, 2, 2</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>诊断信息</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="button_Copy.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="button_Copy" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="propertyGrid" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Copy.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid.Name" xml:space="preserve">
|
||||
<value>propertyGrid</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>panel1.Name" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>655, 377</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>DiagnosticsDialog</value>
|
||||
</data>
|
||||
<data name="propertyGrid.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="button_Copy.Text" xml:space="preserve">
|
||||
<value>复制到剪贴板</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>655, 377</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="propertyGrid.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>579, 313</value>
|
||||
</data>
|
||||
<data name=">>button_Copy.Name" xml:space="preserve">
|
||||
<value>button_Copy</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>button_Copy.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name="button_Copy.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>229, 325</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>propertyGrid.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.PropertyGrid, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Copy.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>7, 0, 7, 0</value>
|
||||
</data>
|
||||
<data name="propertyGrid.HelpVisible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>36, 12, 36, 8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>583, 357</value>
|
||||
</data>
|
||||
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>panel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="propertyGrid.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>36, 12</value>
|
||||
</data>
|
||||
<metadata name="$this.Language" type="System.Globalization.CultureInfo, System.Private.CoreLib, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>en</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
112
SpineViewer/Dialogs/ExportDialog.Designer.cs
generated
Normal file
112
SpineViewer/Dialogs/ExportDialog.Designer.cs
generated
Normal file
@@ -0,0 +1,112 @@
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
partial class ExportDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExportDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
propertyGrid_ExportArgs = new PropertyGrid();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(propertyGrid_ExportArgs, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 1);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// propertyGrid_ExportArgs
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_ExportArgs, "propertyGrid_ExportArgs");
|
||||
propertyGrid_ExportArgs.Name = "propertyGrid_ExportArgs";
|
||||
propertyGrid_ExportArgs.PropertySort = PropertySort.Categorized;
|
||||
propertyGrid_ExportArgs.ToolbarVisible = false;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel2, "tableLayoutPanel2");
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
resources.ApplyResources(button_Ok, "button_Ok");
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
resources.ApplyResources(button_Cancel, "button_Cancel");
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// ExportDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
Controls.Add(panel1);
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ExportDialog";
|
||||
ShowInTaskbar = false;
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
private Button button_Cancel;
|
||||
private PropertyGrid propertyGrid_ExportArgs;
|
||||
}
|
||||
}
|
||||
79
SpineViewer/Dialogs/ExportDialog.cs
Normal file
79
SpineViewer/Dialogs/ExportDialog.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using SpineViewer.Spine.SpineExporter;
|
||||
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ExportDialog : Form
|
||||
{
|
||||
private readonly ExporterProperty wrapper;
|
||||
|
||||
public ExportDialog(ExporterProperty wrapper)
|
||||
{
|
||||
InitializeComponent();
|
||||
this.wrapper = wrapper;
|
||||
propertyGrid_ExportArgs.SelectedObject = wrapper;
|
||||
|
||||
#region XXX: 通过反射默认高亮指定的项
|
||||
var categories = propertyGrid_ExportArgs.SelectedGridItem?.Parent?.Parent?.GridItems;
|
||||
if (categories is null) return;
|
||||
|
||||
foreach (var category in categories)
|
||||
{
|
||||
// 查找 "导出" 分组
|
||||
if (category == null) continue;
|
||||
PropertyInfo? labelProp = category.GetType().GetProperty("Label", BindingFlags.Instance | BindingFlags.Public);
|
||||
if (labelProp == null) continue;
|
||||
string? label = labelProp.GetValue(category) as string;
|
||||
if (label != "[0] 导出") continue;
|
||||
|
||||
// 获取该分组下的所有属性项
|
||||
PropertyInfo? gridItemsProp = category.GetType().GetProperty("GridItems", BindingFlags.Instance | BindingFlags.Public);
|
||||
if (gridItemsProp == null) continue;
|
||||
var gridItemsObj = gridItemsProp.GetValue(category);
|
||||
if (gridItemsObj is not IEnumerable gridItems) continue;
|
||||
|
||||
foreach (object item in gridItems)
|
||||
{
|
||||
if (item == null) continue;
|
||||
PropertyInfo? propDescProp = item.GetType().GetProperty("PropertyDescriptor", BindingFlags.Instance | BindingFlags.Public);
|
||||
if (propDescProp == null) continue;
|
||||
var propDesc = propDescProp.GetValue(item) as PropertyDescriptor;
|
||||
if (propDesc == null) continue;
|
||||
if (propDesc.Name == "OutputDir")
|
||||
{
|
||||
|
||||
if (item is GridItem gridItem)
|
||||
propertyGrid_ExportArgs.SelectedGridItem = gridItem; // 找到后,将此项设为选中项
|
||||
else
|
||||
propertyGrid_ExportArgs.SelectedGridItem = (GridItem)item; // 如果转换失败,则尝试直接赋值
|
||||
}
|
||||
return; // 设置成功后退出
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
private void button_Ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (wrapper.Exporter.Validate() is string error)
|
||||
{
|
||||
MessagePopup.Info(error, Properties.Resources.parameterError);
|
||||
return;
|
||||
}
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void button_Cancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
}
|
||||
3276
SpineViewer/Dialogs/ExportDialog.en.resx
Normal file
3276
SpineViewer/Dialogs/ExportDialog.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
3495
SpineViewer/Dialogs/ExportDialog.resx
Normal file
3495
SpineViewer/Dialogs/ExportDialog.resx
Normal file
File diff suppressed because it is too large
Load Diff
269
SpineViewer/Dialogs/ExportPngDialog.Designer.cs
generated
269
SpineViewer/Dialogs/ExportPngDialog.Designer.cs
generated
@@ -1,269 +0,0 @@
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
partial class ExportPngDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExportPngDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label4 = new Label();
|
||||
label1 = new Label();
|
||||
label2 = new Label();
|
||||
label3 = new Label();
|
||||
textBox_OutputDir = new TextBox();
|
||||
button_SelectOutputDir = new Button();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
numericUpDown_Duration = new NumericUpDown();
|
||||
numericUpDown_Fps = new NumericUpDown();
|
||||
folderBrowserDialog = new FolderBrowserDialog();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)numericUpDown_Duration).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)numericUpDown_Fps).BeginInit();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(0, 0);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(50, 15, 50, 10);
|
||||
panel1.Size = new Size(919, 276);
|
||||
panel1.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.AutoSize = true;
|
||||
tableLayoutPanel1.ColumnCount = 4;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label1, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(label2, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 3);
|
||||
tableLayoutPanel1.Controls.Add(textBox_OutputDir, 1, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectOutputDir, 3, 1);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 4);
|
||||
tableLayoutPanel1.Controls.Add(numericUpDown_Duration, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(numericUpDown_Fps, 1, 3);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(50, 15);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 5;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(819, 251);
|
||||
tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.AutoSize = true;
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Dock = DockStyle.Fill;
|
||||
label4.Location = new Point(15, 15);
|
||||
label4.Margin = new Padding(15);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new Size(789, 24);
|
||||
label4.TabIndex = 11;
|
||||
label4.Text = "说明:时长不足一帧时仅导出第一帧";
|
||||
label4.TextAlign = ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.Anchor = AnchorStyles.Right;
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new Point(3, 62);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(104, 24);
|
||||
label1.TabIndex = 0;
|
||||
label1.Text = "输出文件夹:";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.Anchor = AnchorStyles.Right;
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new Point(57, 100);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new Size(50, 24);
|
||||
label2.TabIndex = 1;
|
||||
label2.Text = "时长:";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Anchor = AnchorStyles.Right;
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new Point(57, 136);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new Size(50, 24);
|
||||
label3.TabIndex = 2;
|
||||
label3.Text = "帧率:";
|
||||
//
|
||||
// textBox_OutputDir
|
||||
//
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_OutputDir, 2);
|
||||
textBox_OutputDir.Dock = DockStyle.Fill;
|
||||
textBox_OutputDir.Location = new Point(113, 57);
|
||||
textBox_OutputDir.Name = "textBox_OutputDir";
|
||||
textBox_OutputDir.Size = new Size(664, 30);
|
||||
textBox_OutputDir.TabIndex = 3;
|
||||
//
|
||||
// button_SelectOutputDir
|
||||
//
|
||||
button_SelectOutputDir.AutoSize = true;
|
||||
button_SelectOutputDir.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
button_SelectOutputDir.Location = new Point(783, 57);
|
||||
button_SelectOutputDir.Name = "button_SelectOutputDir";
|
||||
button_SelectOutputDir.Size = new Size(32, 34);
|
||||
button_SelectOutputDir.TabIndex = 5;
|
||||
button_SelectOutputDir.Text = "...";
|
||||
button_SelectOutputDir.UseVisualStyleBackColor = true;
|
||||
button_SelectOutputDir.Click += button_SelectOutputDir_Click;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
tableLayoutPanel2.AutoSize = true;
|
||||
tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||
tableLayoutPanel2.ColumnCount = 2;
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Dock = DockStyle.Bottom;
|
||||
tableLayoutPanel2.Location = new Point(3, 208);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
tableLayoutPanel2.RowCount = 1;
|
||||
tableLayoutPanel2.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel2.Size = new Size(813, 40);
|
||||
tableLayoutPanel2.TabIndex = 10;
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
button_Ok.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
|
||||
button_Ok.Location = new Point(264, 3);
|
||||
button_Ok.Margin = new Padding(3, 3, 30, 3);
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.Size = new Size(112, 34);
|
||||
button_Ok.TabIndex = 7;
|
||||
button_Ok.Text = "确认";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
button_Cancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
|
||||
button_Cancel.Location = new Point(436, 3);
|
||||
button_Cancel.Margin = new Padding(30, 3, 3, 3);
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.Size = new Size(112, 34);
|
||||
button_Cancel.TabIndex = 8;
|
||||
button_Cancel.Text = "取消";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// numericUpDown_Duration
|
||||
//
|
||||
numericUpDown_Duration.Anchor = AnchorStyles.Left;
|
||||
numericUpDown_Duration.DecimalPlaces = 3;
|
||||
numericUpDown_Duration.Location = new Point(113, 97);
|
||||
numericUpDown_Duration.Maximum = new decimal(new int[] { 300, 0, 0, 0 });
|
||||
numericUpDown_Duration.Name = "numericUpDown_Duration";
|
||||
numericUpDown_Duration.Size = new Size(180, 30);
|
||||
numericUpDown_Duration.TabIndex = 12;
|
||||
numericUpDown_Duration.TextAlign = HorizontalAlignment.Right;
|
||||
numericUpDown_Duration.Value = new decimal(new int[] { 1, 0, 0, 0 });
|
||||
//
|
||||
// numericUpDown_Fps
|
||||
//
|
||||
numericUpDown_Fps.Anchor = AnchorStyles.Left;
|
||||
numericUpDown_Fps.Location = new Point(113, 133);
|
||||
numericUpDown_Fps.Maximum = new decimal(new int[] { 300, 0, 0, 0 });
|
||||
numericUpDown_Fps.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
|
||||
numericUpDown_Fps.Name = "numericUpDown_Fps";
|
||||
numericUpDown_Fps.Size = new Size(180, 30);
|
||||
numericUpDown_Fps.TabIndex = 13;
|
||||
numericUpDown_Fps.TextAlign = HorizontalAlignment.Right;
|
||||
numericUpDown_Fps.Value = new decimal(new int[] { 60, 0, 0, 0 });
|
||||
//
|
||||
// folderBrowserDialog
|
||||
//
|
||||
folderBrowserDialog.AddToRecent = false;
|
||||
//
|
||||
// ExportPngDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
ClientSize = new Size(919, 276);
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
Icon = (Icon)resources.GetObject("$this.Icon");
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ExportPngDialog";
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "导出PNG序列";
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)numericUpDown_Duration).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)numericUpDown_Fps).EndInit();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Label label4;
|
||||
private Label label1;
|
||||
private Label label2;
|
||||
private Label label3;
|
||||
private TextBox textBox_OutputDir;
|
||||
private Button button_SelectOutputDir;
|
||||
private TableLayoutPanel tableLayoutPanel2;
|
||||
private Button button_Ok;
|
||||
private Button button_Cancel;
|
||||
private NumericUpDown numericUpDown_Duration;
|
||||
private NumericUpDown numericUpDown_Fps;
|
||||
private FolderBrowserDialog folderBrowserDialog;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ExportPngDialog : Form
|
||||
{
|
||||
public string OutputDir { get; private set; }
|
||||
public float Duration { get; private set; }
|
||||
public uint Fps { get; private set; }
|
||||
|
||||
public ExportPngDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void button_SelectOutputDir_Click(object sender, EventArgs e)
|
||||
{
|
||||
folderBrowserDialog.InitialDirectory = textBox_OutputDir.Text;
|
||||
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
textBox_OutputDir.Text = Path.GetFullPath(folderBrowserDialog.SelectedPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void button_Ok_Click(object sender, EventArgs e)
|
||||
{
|
||||
var outputDir = textBox_OutputDir.Text;
|
||||
if (File.Exists(outputDir))
|
||||
{
|
||||
MessageBox.Show("输出文件夹无效", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Directory.Exists(outputDir))
|
||||
{
|
||||
if (MessageBox.Show($"文件夹 {outputDir} 不存在,是否创建?", "操作确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(outputDir);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Program.Logger.Error(ex.ToString());
|
||||
MessageBox.Show(ex.ToString(), "文件夹创建失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
OutputDir = Path.GetFullPath(outputDir);
|
||||
Duration = (float)numericUpDown_Duration.Value;
|
||||
Fps = (uint)numericUpDown_Fps.Value;
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
private void button_Cancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
}
|
||||
405
SpineViewer/Dialogs/OpenSpineDialog.Designer.cs
generated
405
SpineViewer/Dialogs/OpenSpineDialog.Designer.cs
generated
@@ -20,253 +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|所有文件 (*.*)|*.*";
|
||||
//
|
||||
// openFileDialog_Atlas
|
||||
//
|
||||
openFileDialog_Atlas.AddExtension = false;
|
||||
openFileDialog_Atlas.AddToRecent = false;
|
||||
openFileDialog_Atlas.Filter = "atlas 文件 (*.atlas)|*.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 = "打开骨骼";
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OpenSpineDialog));
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
label4 = new Label();
|
||||
label1 = new Label();
|
||||
label2 = new Label();
|
||||
label3 = new Label();
|
||||
textBox_SkelPath = new TextBox();
|
||||
button_SelectSkel = new Button();
|
||||
button_SelectAtlas = new Button();
|
||||
comboBox_Version = new ComboBox();
|
||||
textBox_AtlasPath = new TextBox();
|
||||
tableLayoutPanel2 = new TableLayoutPanel();
|
||||
button_Ok = new Button();
|
||||
button_Cancel = new Button();
|
||||
openFileDialog_Skel = new OpenFileDialog();
|
||||
openFileDialog_Atlas = new OpenFileDialog();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
tableLayoutPanel2.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(label4, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(label1, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(label2, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label3, 0, 3);
|
||||
tableLayoutPanel1.Controls.Add(textBox_SkelPath, 1, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectSkel, 3, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_SelectAtlas, 3, 2);
|
||||
tableLayoutPanel1.Controls.Add(comboBox_Version, 1, 3);
|
||||
tableLayoutPanel1.Controls.Add(textBox_AtlasPath, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(tableLayoutPanel2, 0, 4);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
resources.ApplyResources(label4, "label4");
|
||||
tableLayoutPanel1.SetColumnSpan(label4, 4);
|
||||
label4.Name = "label4";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
resources.ApplyResources(label1, "label1");
|
||||
label1.Name = "label1";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
resources.ApplyResources(label2, "label2");
|
||||
label2.Name = "label2";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(label3, "label3");
|
||||
label3.Name = "label3";
|
||||
//
|
||||
// textBox_SkelPath
|
||||
//
|
||||
resources.ApplyResources(textBox_SkelPath, "textBox_SkelPath");
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_SkelPath, 2);
|
||||
textBox_SkelPath.Name = "textBox_SkelPath";
|
||||
//
|
||||
// button_SelectSkel
|
||||
//
|
||||
resources.ApplyResources(button_SelectSkel, "button_SelectSkel");
|
||||
button_SelectSkel.Name = "button_SelectSkel";
|
||||
button_SelectSkel.UseVisualStyleBackColor = true;
|
||||
button_SelectSkel.Click += button_SelectSkel_Click;
|
||||
//
|
||||
// button_SelectAtlas
|
||||
//
|
||||
resources.ApplyResources(button_SelectAtlas, "button_SelectAtlas");
|
||||
button_SelectAtlas.Name = "button_SelectAtlas";
|
||||
button_SelectAtlas.UseVisualStyleBackColor = true;
|
||||
button_SelectAtlas.Click += button_SelectAtlas_Click;
|
||||
//
|
||||
// comboBox_Version
|
||||
//
|
||||
resources.ApplyResources(comboBox_Version, "comboBox_Version");
|
||||
comboBox_Version.DropDownStyle = ComboBoxStyle.DropDownList;
|
||||
comboBox_Version.FormattingEnabled = true;
|
||||
comboBox_Version.Name = "comboBox_Version";
|
||||
comboBox_Version.Sorted = true;
|
||||
//
|
||||
// textBox_AtlasPath
|
||||
//
|
||||
resources.ApplyResources(textBox_AtlasPath, "textBox_AtlasPath");
|
||||
tableLayoutPanel1.SetColumnSpan(textBox_AtlasPath, 2);
|
||||
textBox_AtlasPath.Name = "textBox_AtlasPath";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel2, "tableLayoutPanel2");
|
||||
tableLayoutPanel1.SetColumnSpan(tableLayoutPanel2, 4);
|
||||
tableLayoutPanel2.Controls.Add(button_Ok, 0, 0);
|
||||
tableLayoutPanel2.Controls.Add(button_Cancel, 1, 0);
|
||||
tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
//
|
||||
// button_Ok
|
||||
//
|
||||
resources.ApplyResources(button_Ok, "button_Ok");
|
||||
button_Ok.Name = "button_Ok";
|
||||
button_Ok.UseVisualStyleBackColor = true;
|
||||
button_Ok.Click += button_Ok_Click;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
resources.ApplyResources(button_Cancel, "button_Cancel");
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// openFileDialog_Skel
|
||||
//
|
||||
openFileDialog_Skel.AddExtension = false;
|
||||
openFileDialog_Skel.AddToRecent = false;
|
||||
resources.ApplyResources(openFileDialog_Skel, "openFileDialog_Skel");
|
||||
//
|
||||
// openFileDialog_Atlas
|
||||
//
|
||||
openFileDialog_Atlas.AddExtension = false;
|
||||
openFileDialog_Atlas.AddToRecent = false;
|
||||
resources.ApplyResources(openFileDialog_Atlas, "openFileDialog_Atlas");
|
||||
//
|
||||
// OpenSpineDialog
|
||||
//
|
||||
AcceptButton = button_Ok;
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
CancelButton = button_Cancel;
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "OpenSpineDialog";
|
||||
ShowInTaskbar = false;
|
||||
Load += OpenSpineDialog_Load;
|
||||
panel1.ResumeLayout(false);
|
||||
panel1.PerformLayout();
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
tableLayoutPanel2.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
private Panel panel1;
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private Label label1;
|
||||
private Label label2;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SpineViewer.Spine;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
@@ -8,22 +9,27 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class OpenSpineDialog : Form
|
||||
{
|
||||
public string SkelPath { get; private set; }
|
||||
public string? AtlasPath { get; private set; }
|
||||
public Spine.Version Version { get; private set; }
|
||||
/// <summary>
|
||||
/// 对话框结果
|
||||
/// </summary>
|
||||
public OpenSpineDialogResult Result { get; private set; }
|
||||
|
||||
public OpenSpineDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
comboBox_Version.DataSource = VersionHelper.Versions.ToList();
|
||||
comboBox_Version.DataSource = SpineUtils.Names.ToList();
|
||||
comboBox_Version.DisplayMember = "Value";
|
||||
comboBox_Version.ValueMember = "Key";
|
||||
comboBox_Version.SelectedValue = Spine.Version.V38;
|
||||
comboBox_Version.SelectedValue = SpineVersion.Auto;
|
||||
}
|
||||
|
||||
private void OpenSpineDialog_Load(object sender, EventArgs e)
|
||||
{
|
||||
button_SelectSkel_Click(sender, e);
|
||||
}
|
||||
|
||||
private void button_SelectSkel_Click(object sender, EventArgs e)
|
||||
@@ -48,10 +54,11 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
var skelPath = textBox_SkelPath.Text;
|
||||
var atlasPath = textBox_AtlasPath.Text;
|
||||
var version = (SpineVersion)comboBox_Version.SelectedValue;
|
||||
|
||||
if (!File.Exists(skelPath))
|
||||
{
|
||||
MessageBox.Show($"{skelPath}", "skel文件不存在", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessagePopup.Info($"{skelPath}", Properties.Resources.skelNotExist);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -59,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.Show($"{atlasPath}", "atlas文件不存在", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
MessagePopup.Info($"{atlasPath}", Properties.Resources.atlasNotExist);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -73,10 +80,13 @@ namespace SpineViewer.Dialogs
|
||||
atlasPath = Path.GetFullPath(atlasPath);
|
||||
}
|
||||
|
||||
SkelPath = skelPath;
|
||||
AtlasPath = atlasPath;
|
||||
Version = (Spine.Version)comboBox_Version.SelectedValue;
|
||||
if (version != SpineVersion.Auto && !Spine.SpineObject.HasImplementation(version))
|
||||
{
|
||||
MessagePopup.Info($"{version.GetName()} 版本尚未实现(咕咕咕~)", Properties.Resources.msgBoxInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
Result = new(version, skelPath, atlasPath);
|
||||
DialogResult = DialogResult.OK;
|
||||
}
|
||||
|
||||
@@ -85,4 +95,25 @@ namespace SpineViewer.Dialogs
|
||||
DialogResult = DialogResult.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开骨骼对话框结果
|
||||
/// </summary>
|
||||
public class OpenSpineDialogResult(SpineVersion version, string skelPath, string? atlasPath = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// 版本
|
||||
/// </summary>
|
||||
public SpineVersion Version => version;
|
||||
|
||||
/// <summary>
|
||||
/// skel 文件路径
|
||||
/// </summary>
|
||||
public string SkelPath => skelPath;
|
||||
|
||||
/// <summary>
|
||||
/// atlas 文件路径
|
||||
/// </summary>
|
||||
public string? AtlasPath => atlasPath;
|
||||
}
|
||||
}
|
||||
|
||||
3324
SpineViewer/Dialogs/OpenSpineDialog.en.resx
Normal file
3324
SpineViewer/Dialogs/OpenSpineDialog.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -117,13 +117,232 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="openFileDialog_Skel.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>75, 24</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog_Atlas.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>317, 22</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_SelectSkel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label3.Name" xml:space="preserve">
|
||||
<value>label3</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Cancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left</value>
|
||||
</data>
|
||||
<data name=">>button_SelectAtlas.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>textBox_AtlasPath.ZOrder" xml:space="preserve">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label4" Row="0" RowSpan="1" Column="0" ColumnSpan="4" /><Control Name="label1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label2" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label3" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textBox_SkelPath" Row="1" RowSpan="1" Column="1" ColumnSpan="2" /><Control Name="button_SelectSkel" Row="1" RowSpan="1" Column="3" ColumnSpan="1" /><Control Name="button_SelectAtlas" Row="2" RowSpan="1" Column="3" ColumnSpan="1" /><Control Name="comboBox_Version" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textBox_AtlasPath" Row="2" RowSpan="1" Column="1" ColumnSpan="2" /><Control Name="tableLayoutPanel2" Row="4" RowSpan="1" Column="0" ColumnSpan="4" /></Controls><Columns Styles="AutoSize,0,Percent,50,Percent,50,AutoSize,0" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name="label2.Text" xml:space="preserve">
|
||||
<value>atlas文件路径:</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel2.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>label3.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>skel文件路径:</value>
|
||||
</data>
|
||||
<data name=">>button_SelectSkel.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name="button_Ok.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 22, 2</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="textBox_SkelPath.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>109, 46</value>
|
||||
</data>
|
||||
<data name="label4.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>label1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button_SelectAtlas.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name=">>label3.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label4.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="textBox_SkelPath.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>textBox_AtlasPath.Name" xml:space="preserve">
|
||||
<value>textBox_AtlasPath</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>314, 2</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>133, 28</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Atlas.Filter" xml:space="preserve">
|
||||
<value>所有文件 (*.*)|*.*|atlas 文件 (*.atlas)|*.atlas</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>button_SelectSkel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.Text" xml:space="preserve">
|
||||
<value>...</value>
|
||||
</data>
|
||||
<data name=">>panel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>panel1.Name" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Skel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 85</value>
|
||||
</data>
|
||||
<data name=">>textBox_SkelPath.Name" xml:space="preserve">
|
||||
<value>textBox_SkelPath</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label2.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Atlas.Name" xml:space="preserve">
|
||||
<value>openFileDialog_Atlas</value>
|
||||
</data>
|
||||
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>566, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 184</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label4.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>557, 80</value>
|
||||
</data>
|
||||
<data name="button_Ok.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="label3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name=">>panel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label3.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Name" xml:space="preserve">
|
||||
<value>button_Ok</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="label1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Title" xml:space="preserve">
|
||||
<value>选择skel文件</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name="textBox_SkelPath.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="label3.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>button_SelectSkel.Name" xml:space="preserve">
|
||||
<value>button_SelectSkel</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>36, 12, 36, 8</value>
|
||||
</data>
|
||||
<data name=">>textBox_SkelPath.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>444, 27</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ComboBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.RowCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>textBox_SkelPath.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>textBox_SkelPath.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>588, 218</value>
|
||||
</data>
|
||||
<data name="button_Ok.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>189, 2</value>
|
||||
</data>
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAkAEBAAAAEAIABoBAAAlgAAABgYAAABACAAiAkAAP4EAAAgIAAAAQAgAKgQAACGDgAAMDAAAAEA
|
||||
@@ -3270,4 +3489,292 @@
|
||||
////////wAAAAAAAB///////
|
||||
</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>584, 32</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>22, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="label3.Text" xml:space="preserve">
|
||||
<value>版本:</value>
|
||||
</data>
|
||||
<data name=">>label1.Name" xml:space="preserve">
|
||||
<value>label1</value>
|
||||
</data>
|
||||
<data name="button_Ok.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name=">>label4.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>textBox_AtlasPath.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>103, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="button_Ok.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Right</value>
|
||||
</data>
|
||||
<data name="textBox_SkelPath.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>label1.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>557, 46</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>label4.Name" xml:space="preserve">
|
||||
<value>label4</value>
|
||||
</data>
|
||||
<data name="label1.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>OpenSpineDialog</value>
|
||||
</data>
|
||||
<data name=">>button_SelectAtlas.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Ok.Text" xml:space="preserve">
|
||||
<value>确认</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.Text" xml:space="preserve">
|
||||
<value>...</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>button_SelectSkel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label2.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="label4.Text" xml:space="preserve">
|
||||
<value>说明:如果没有选择atlas,则会自动读取与skel同目录下同名的atlas文件</value>
|
||||
</data>
|
||||
<data name="label4.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>11, 12, 11, 12</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name="label4.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>11, 12</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>28, 30</value>
|
||||
</data>
|
||||
<data name="button_SelectAtlas.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="label1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Atlas.Title" xml:space="preserve">
|
||||
<value>选择atlas文件</value>
|
||||
</data>
|
||||
<data name="label3.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Atlas.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label2.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.ZOrder" xml:space="preserve">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Name" xml:space="preserve">
|
||||
<value>comboBox_Version</value>
|
||||
</data>
|
||||
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>63, 118</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>660, 238</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>109, 114</value>
|
||||
</data>
|
||||
<data name=">>label2.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>97, 20</value>
|
||||
</data>
|
||||
<data name="label4.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="label4.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>MiddleCenter</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.ZOrder" xml:space="preserve">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="button_Cancel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel2.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel2.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="button_Ok" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="button_Cancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>109, 80</value>
|
||||
</data>
|
||||
<data name="label2.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Name" xml:space="preserve">
|
||||
<value>button_Cancel</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>28, 30</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>comboBox_Version.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="label2.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Right</value>
|
||||
</data>
|
||||
<data name=">>label1.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="textBox_SkelPath.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>444, 27</value>
|
||||
</data>
|
||||
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>42, 20</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name=">>button_SelectAtlas.Name" xml:space="preserve">
|
||||
<value>button_SelectAtlas</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>打开骨骼</value>
|
||||
</data>
|
||||
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>8, 51</value>
|
||||
</data>
|
||||
<data name=">>label2.Name" xml:space="preserve">
|
||||
<value>label2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>36, 12</value>
|
||||
</data>
|
||||
<data name=">>openFileDialog_Skel.Name" xml:space="preserve">
|
||||
<value>openFileDialog_Skel</value>
|
||||
</data>
|
||||
<data name="openFileDialog_Skel.Filter" xml:space="preserve">
|
||||
<value>所有文件 (*.*)|*.*|skel 文件 (*.skel; *.json)|*.skel;*.json</value>
|
||||
</data>
|
||||
<data name="label3.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 0, 2, 0</value>
|
||||
</data>
|
||||
<data name="label4.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>660, 238</value>
|
||||
</data>
|
||||
<data name=">>panel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name=">>button_Ok.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel2</value>
|
||||
</data>
|
||||
<data name=">>textBox_AtlasPath.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="textBox_AtlasPath.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name="button_SelectSkel.AutoSizeMode" type="System.Windows.Forms.AutoSizeMode, System.Windows.Forms">
|
||||
<value>GrowAndShrink</value>
|
||||
</data>
|
||||
<data name="comboBox_Version.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Left</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="label2.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Language" type="System.Globalization.CultureInfo, System.Private.CoreLib, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>en</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog_Atlas.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>349, 29</value>
|
||||
</metadata>
|
||||
<metadata name="openFileDialog_Skel.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>58, 25</value>
|
||||
</metadata>
|
||||
</root>
|
||||
181
SpineViewer/Dialogs/ProgressDialog.Designer.cs
generated
181
SpineViewer/Dialogs/ProgressDialog.Designer.cs
generated
@@ -20,114 +20,85 @@
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
progressBar = new ProgressBar();
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
button_Cancel = new Button();
|
||||
label_Tip = new Label();
|
||||
backgroundWorker = new System.ComponentModel.BackgroundWorker();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// progressBar
|
||||
//
|
||||
progressBar.Dock = DockStyle.Fill;
|
||||
progressBar.Location = new Point(3, 57);
|
||||
progressBar.Name = "progressBar";
|
||||
progressBar.Size = new Size(552, 34);
|
||||
progressBar.Style = ProgressBarStyle.Continuous;
|
||||
progressBar.TabIndex = 0;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Dock = DockStyle.Fill;
|
||||
panel1.Location = new Point(0, 0);
|
||||
panel1.Name = "panel1";
|
||||
panel1.Padding = new Padding(30);
|
||||
panel1.Size = new Size(618, 206);
|
||||
panel1.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.ColumnCount = 1;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.Controls.Add(progressBar, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_Cancel, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label_Tip, 0, 0);
|
||||
tableLayoutPanel1.Dock = DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new Point(30, 30);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 3;
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new RowStyle());
|
||||
tableLayoutPanel1.Size = new Size(558, 146);
|
||||
tableLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
button_Cancel.Anchor = AnchorStyles.Bottom;
|
||||
button_Cancel.Location = new Point(223, 109);
|
||||
button_Cancel.Margin = new Padding(3, 15, 3, 3);
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.Size = new Size(112, 34);
|
||||
button_Cancel.TabIndex = 9;
|
||||
button_Cancel.Text = "取消";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// label_Tip
|
||||
//
|
||||
label_Tip.AutoSize = true;
|
||||
label_Tip.Dock = DockStyle.Fill;
|
||||
label_Tip.Location = new Point(3, 10);
|
||||
label_Tip.Margin = new Padding(3, 10, 3, 10);
|
||||
label_Tip.Name = "label_Tip";
|
||||
label_Tip.Size = new Size(552, 34);
|
||||
label_Tip.TabIndex = 10;
|
||||
label_Tip.Text = "初始化...";
|
||||
//
|
||||
// backgroundWorker
|
||||
//
|
||||
backgroundWorker.WorkerReportsProgress = true;
|
||||
backgroundWorker.WorkerSupportsCancellation = true;
|
||||
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
|
||||
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
|
||||
//
|
||||
// ProgressDialog
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(11F, 24F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(618, 206);
|
||||
ControlBox = false;
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ProgressDialog";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.CenterScreen;
|
||||
Text = "进度";
|
||||
panel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ProgressDialog));
|
||||
progressBar = new ProgressBar();
|
||||
panel1 = new Panel();
|
||||
tableLayoutPanel1 = new TableLayoutPanel();
|
||||
button_Cancel = new Button();
|
||||
label_Tip = new Label();
|
||||
backgroundWorker = new System.ComponentModel.BackgroundWorker();
|
||||
panel1.SuspendLayout();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// progressBar
|
||||
//
|
||||
resources.ApplyResources(progressBar, "progressBar");
|
||||
progressBar.Name = "progressBar";
|
||||
progressBar.Style = ProgressBarStyle.Continuous;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
resources.ApplyResources(panel1, "panel1");
|
||||
panel1.Controls.Add(tableLayoutPanel1);
|
||||
panel1.Name = "panel1";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
resources.ApplyResources(tableLayoutPanel1, "tableLayoutPanel1");
|
||||
tableLayoutPanel1.Controls.Add(progressBar, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(button_Cancel, 0, 2);
|
||||
tableLayoutPanel1.Controls.Add(label_Tip, 0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
//
|
||||
// button_Cancel
|
||||
//
|
||||
resources.ApplyResources(button_Cancel, "button_Cancel");
|
||||
button_Cancel.Name = "button_Cancel";
|
||||
button_Cancel.UseVisualStyleBackColor = true;
|
||||
button_Cancel.Click += button_Cancel_Click;
|
||||
//
|
||||
// label_Tip
|
||||
//
|
||||
resources.ApplyResources(label_Tip, "label_Tip");
|
||||
label_Tip.Name = "label_Tip";
|
||||
//
|
||||
// backgroundWorker
|
||||
//
|
||||
backgroundWorker.WorkerReportsProgress = true;
|
||||
backgroundWorker.WorkerSupportsCancellation = true;
|
||||
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
|
||||
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
|
||||
//
|
||||
// ProgressDialog
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ControlBox = false;
|
||||
Controls.Add(panel1);
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "ProgressDialog";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
panel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
tableLayoutPanel1.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private ProgressBar progressBar;
|
||||
private Panel panel1;
|
||||
private TableLayoutPanel tableLayoutPanel1;
|
||||
private System.ComponentModel.BackgroundWorker backgroundWorker;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using NLog;
|
||||
using SpineViewer.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
@@ -12,21 +14,33 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
public partial class ProgressDialog : Form
|
||||
{
|
||||
[Category("自定义"), Description("BackgroundWorker 的 DoWork 事件")]
|
||||
public event DoWorkEventHandler? DoWork
|
||||
{
|
||||
add { backgroundWorker.DoWork += value; }
|
||||
remove { backgroundWorker.DoWork -= value; }
|
||||
}
|
||||
|
||||
public void RunWorkerAsync() { backgroundWorker.RunWorkerAsync(); }
|
||||
public void RunWorkerAsync(object? argument) { backgroundWorker.RunWorkerAsync(argument); }
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public ProgressDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// BackgroundWorker.DoWork 接口暴露
|
||||
/// </summary>
|
||||
[Category("自定义"), Description("BackgroundWorker 的 DoWork 事件")]
|
||||
public event DoWorkEventHandler? DoWork
|
||||
{
|
||||
add => backgroundWorker.DoWork += value;
|
||||
remove => backgroundWorker.DoWork -= value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动后台执行
|
||||
/// </summary>
|
||||
public void RunWorkerAsync() => backgroundWorker.RunWorkerAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 使用给定参数启动后台执行
|
||||
/// </summary>
|
||||
public void RunWorkerAsync(object? argument) => backgroundWorker.RunWorkerAsync(argument);
|
||||
|
||||
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
|
||||
{
|
||||
label_Tip.Text = e.UserState as string;
|
||||
@@ -37,8 +51,8 @@ namespace SpineViewer.Dialogs
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
Program.Logger.Error(e.Error.ToString());
|
||||
MessageBox.Show(e.Error.ToString(), "执行出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
logger.Error(e.Error.ToString());
|
||||
MessagePopup.Error(e.Error.ToString(), Properties.Resources.runtimeError);
|
||||
DialogResult = DialogResult.Abort;
|
||||
}
|
||||
else if (e.Cancelled)
|
||||
|
||||
129
SpineViewer/Dialogs/ProgressDialog.en.resx
Normal file
129
SpineViewer/Dialogs/ProgressDialog.en.resx
Normal file
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="label_Tip.Text" xml:space="preserve">
|
||||
<value>Initializing...</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Progress</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,6 +117,199 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name=">>button_Cancel.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Text" xml:space="preserve">
|
||||
<value>取消</value>
|
||||
</data>
|
||||
<data name=">>panel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="tableLayoutPanel1.ColumnCount" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="button_Cancel.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom</value>
|
||||
</data>
|
||||
<data name=">>progressBar.Parent" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Parent" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name=">>panel1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name="panel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="button_Cancel.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="tableLayoutPanel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>22, 25</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="label_Tip.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 8, 2, 8</value>
|
||||
</data>
|
||||
<data name="panel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Name" xml:space="preserve">
|
||||
<value>label_Tip</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Name" xml:space="preserve">
|
||||
<value>button_Cancel</value>
|
||||
</data>
|
||||
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
|
||||
<value>8, 20</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.RowCount" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="progressBar.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 50</value>
|
||||
</data>
|
||||
<data name="label_Tip.Text" xml:space="preserve">
|
||||
<value>初始化...</value>
|
||||
</data>
|
||||
<data name="label_Tip.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name=">>backgroundWorker.Type" xml:space="preserve">
|
||||
<value>System.ComponentModel.BackgroundWorker, System.ComponentModel.EventBasedAsync, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.LayoutSettings" type="System.Windows.Forms.TableLayoutSettings, System.Windows.Forms">
|
||||
<value><?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="progressBar" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="button_Cancel" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="label_Tip" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0,AutoSize,0" /></TableLayoutSettings></value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 12, 2, 2</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.Name" xml:space="preserve">
|
||||
<value>tableLayoutPanel1</value>
|
||||
</data>
|
||||
<data name=">>progressBar.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ProgressBar, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>81, 28</value>
|
||||
</data>
|
||||
<data name="label_Tip.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="progressBar.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>401, 28</value>
|
||||
</data>
|
||||
<data name="label_Tip.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name=">>progressBar.Name" xml:space="preserve">
|
||||
<value>progressBar</value>
|
||||
</data>
|
||||
<data name=">>panel1.Name" xml:space="preserve">
|
||||
<value>panel1</value>
|
||||
</data>
|
||||
<data name="panel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>449, 172</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>ProgressDialog</value>
|
||||
</data>
|
||||
<data name=">>tableLayoutPanel1.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="progressBar.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="label_Tip.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>2, 8</value>
|
||||
</data>
|
||||
<data name=">>backgroundWorker.Name" xml:space="preserve">
|
||||
<value>backgroundWorker</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="panel1.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>449, 172</value>
|
||||
</data>
|
||||
<data name="label_Tip.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>401, 32</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name="button_Cancel.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>162, 92</value>
|
||||
</data>
|
||||
<data name="panel1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>0, 0</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>进度</value>
|
||||
</data>
|
||||
<data name=">>label_Tip.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="panel1.Padding" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>22, 25, 22, 25</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>405, 122</value>
|
||||
</data>
|
||||
<data name="progressBar.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="tableLayoutPanel1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>panel1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Panel, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button_Cancel.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>progressBar.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<data name="progressBar.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
|
||||
<value>Fill</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="$this.Language" type="System.Globalization.CultureInfo, System.Private.CoreLib, Culture=neutral, PublicKeyToken=7cec85d7bea7798e">
|
||||
<value>en</value>
|
||||
</metadata>
|
||||
<metadata name="backgroundWorker.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
|
||||
21
SpineViewer/Extensions/NLogExtension.cs
Normal file
21
SpineViewer/Extensions/NLogExtension.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpineViewer.Extensions
|
||||
{
|
||||
public static class NLogExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 输出当前进程的内存占用
|
||||
/// </summary>
|
||||
public static void LogCurrentProcessMemoryUsage(this NLog.Logger logger)
|
||||
{
|
||||
var process = Process.GetCurrentProcess();
|
||||
logger.Info("Current memory usage for {}: {:F2} MB", process.ProcessName, process.WorkingSet64 / 1024.0 / 1024.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
118
SpineViewer/Extensions/SFMLExtension.cs
Normal file
118
SpineViewer/Extensions/SFMLExtension.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SpineViewer.Extensions
|
||||
{
|
||||
public static class SFMLExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取并集范围
|
||||
/// </summary>
|
||||
public static RectangleF Union(this RectangleF bounds, RectangleF other)
|
||||
{
|
||||
var x = Math.Min(bounds.X, other.X);
|
||||
var y = Math.Min(bounds.Y, other.Y);
|
||||
var w = Math.Max(bounds.Right, other.Right) - x;
|
||||
var h = Math.Max(bounds.Bottom, other.Bottom) - y;
|
||||
return new(x, y, w, h);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
|
||||
/// </summary>
|
||||
public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution) => GetCanvasBounds(bounds, resolution, new(0), new(0));
|
||||
|
||||
/// <summary>
|
||||
/// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
|
||||
/// </summary>
|
||||
public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution, Padding margin) => GetCanvasBounds(bounds, resolution, margin, new(0));
|
||||
|
||||
/// <summary>
|
||||
/// 获取适合指定画布参数下能够覆盖包围盒的画布视区包围盒
|
||||
/// </summary>
|
||||
public static RectangleF GetCanvasBounds(this RectangleF bounds, Size resolution, Padding margin, Padding padding)
|
||||
{
|
||||
float sizeW = bounds.Width;
|
||||
float sizeH = bounds.Height;
|
||||
float innerW = resolution.Width - padding.Horizontal;
|
||||
float innerH = resolution.Height - padding.Vertical;
|
||||
float scale = Math.Max(Math.Abs(sizeW / innerW), Math.Abs(sizeH / innerH)); // 取两方向上较大的缩放比, 以此让画布可以覆盖内容
|
||||
float scaleW = scale * Math.Sign(sizeW);
|
||||
float scaleH = scale * Math.Sign(sizeH);
|
||||
|
||||
innerW *= scaleW;
|
||||
innerH *= scaleH;
|
||||
|
||||
var x = bounds.X - (innerW - sizeW) / 2 - (margin.Left + padding.Left) * scaleW;
|
||||
var y = bounds.Y - (innerH - sizeH) / 2 - (margin.Top + padding.Top) * scaleH;
|
||||
var w = (resolution.Width + margin.Horizontal) * scaleW;
|
||||
var h = (resolution.Height + margin.Vertical) * scaleH;
|
||||
return new(x, y, w, h);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象
|
||||
/// </summary>
|
||||
public static Bitmap CopyToBitmap(this SFML.Graphics.Image image)
|
||||
{
|
||||
image.SaveToMemory(out var imgBuffer, "bmp");
|
||||
using var stream = new MemoryStream(imgBuffer);
|
||||
using var bitmap = new Bitmap(stream);
|
||||
return new(bitmap); // 必须重复构造一个副本才能摆脱对流的依赖, 否则之后使用会报错
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 Winforms Bitmap 对象, 需要使用 Dispose 释放对象
|
||||
/// </summary>
|
||||
public static Bitmap CopyToBitmap(this SFML.Graphics.Texture texture)
|
||||
{
|
||||
using var image = texture.CopyToImage();
|
||||
return image.CopyToBitmap();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取视区的包围盒
|
||||
/// </summary>
|
||||
public static RectangleF GetBounds(this SFML.Graphics.View view)
|
||||
{
|
||||
return new(
|
||||
view.Center.X - view.Size.X / 2,
|
||||
view.Center.Y - view.Size.Y / 2,
|
||||
view.Size.X,
|
||||
view.Size.Y
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按画布设置视区, 边缘和填充区域将不会出现内容
|
||||
/// </summary>
|
||||
public static void SetViewport(this SFML.Graphics.View view, Size resolution, Padding margin) => SetViewport(view, resolution, margin, new(0));
|
||||
|
||||
/// <summary>
|
||||
/// 按画布设置视区, 边缘和填充区域将不会出现内容
|
||||
/// </summary>
|
||||
public static void SetViewport(this SFML.Graphics.View view, Size resolution, Padding margin, Padding padding)
|
||||
{
|
||||
var innerW = resolution.Width - padding.Horizontal;
|
||||
var innerH = resolution.Height - padding.Vertical;
|
||||
|
||||
float width = resolution.Width + margin.Horizontal;
|
||||
float height = resolution.Height + margin.Vertical;
|
||||
|
||||
view.Viewport = new(
|
||||
(margin.Left + padding.Left) / width,
|
||||
(margin.Top + padding.Top) / height,
|
||||
innerW / width,
|
||||
innerH / height
|
||||
);
|
||||
|
||||
var bounds = view.GetBounds().GetCanvasBounds(new(innerW, innerH));
|
||||
|
||||
view.Center = new(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2);
|
||||
view.Size = new(bounds.Width, bounds.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
51
SpineViewer/Forms/SpinePreviewFullScreenForm.Designer.cs
generated
Normal file
51
SpineViewer/Forms/SpinePreviewFullScreenForm.Designer.cs
generated
Normal file
@@ -0,0 +1,51 @@
|
||||
namespace SpineViewer.Forms
|
||||
{
|
||||
partial class SpinePreviewFullScreenForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
SuspendLayout();
|
||||
//
|
||||
// SpinePreviewFullScreenForm
|
||||
//
|
||||
AutoScaleMode = AutoScaleMode.None;
|
||||
ClientSize = new Size(512, 512);
|
||||
ControlBox = false;
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
Name = "SpinePreviewFullScreenForm";
|
||||
ShowIcon = false;
|
||||
ShowInTaskbar = false;
|
||||
StartPosition = FormStartPosition.Manual;
|
||||
TopMost = true;
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
35
SpineViewer/Forms/SpinePreviewFullScreenForm.cs
Normal file
35
SpineViewer/Forms/SpinePreviewFullScreenForm.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using SpineViewer.Natives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace SpineViewer.Forms
|
||||
{
|
||||
[ToolboxItem(true)]
|
||||
[Designer(typeof(ComponentDesigner), typeof(IDesigner))]
|
||||
[DesignTimeVisible(true)]
|
||||
public partial class SpinePreviewFullScreenForm: Form
|
||||
{
|
||||
public SpinePreviewFullScreenForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override CreateParams CreateParams
|
||||
{
|
||||
get
|
||||
{
|
||||
var cp = base.CreateParams;
|
||||
cp.ExStyle |= Win32.WS_EX_TOOLWINDOW;
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
577
SpineViewer/Forms/SpineViewerForm.Designer.cs
generated
Normal file
577
SpineViewer/Forms/SpineViewerForm.Designer.cs
generated
Normal file
@@ -0,0 +1,577 @@
|
||||
namespace SpineViewer
|
||||
{
|
||||
partial class SpineViewerForm
|
||||
{
|
||||
/// <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()
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SpineViewerForm));
|
||||
splitContainer_MainForm = new SplitContainer();
|
||||
splitContainer_Functional = new SplitContainer();
|
||||
splitContainer_Information = new SplitContainer();
|
||||
groupBox_SkelList = new GroupBox();
|
||||
spineListView = new SpineViewer.Controls.SpineListView();
|
||||
spineViewPropertyGrid = new SpineViewer.Controls.SpineViewPropertyGrid();
|
||||
splitContainer_Config = new SplitContainer();
|
||||
groupBox_PreviewConfig = new GroupBox();
|
||||
propertyGrid_Previewer = new PropertyGrid();
|
||||
groupBox_SkelConfig = new GroupBox();
|
||||
groupBox_Preview = new GroupBox();
|
||||
spinePreviewPanel = new SpineViewer.Controls.SpinePreviewPanel();
|
||||
rtbLog = new RichTextBox();
|
||||
menuStrip = new MenuStrip();
|
||||
toolStripMenuItem_File = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Open = new ToolStripMenuItem();
|
||||
toolStripMenuItem_BatchOpen = new ToolStripMenuItem();
|
||||
toolStripSeparator1 = new ToolStripSeparator();
|
||||
toolStripMenuItem_Export = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportFrame = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportFrameSequence = new ToolStripMenuItem();
|
||||
toolStripSeparator4 = new ToolStripSeparator();
|
||||
toolStripMenuItem_ExportGif = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportWebp = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportAvif = new ToolStripMenuItem();
|
||||
toolStripSeparator5 = new ToolStripSeparator();
|
||||
toolStripMenuItem_ExportMp4 = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportWebm = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportMkv = new ToolStripMenuItem();
|
||||
toolStripMenuItem_ExportMov = new ToolStripMenuItem();
|
||||
toolStripSeparator6 = new ToolStripSeparator();
|
||||
toolStripMenuItem_ExportCustom = new ToolStripMenuItem();
|
||||
toolStripSeparator2 = new ToolStripSeparator();
|
||||
toolStripMenuItem_Exit = new ToolStripMenuItem();
|
||||
toolStripMenuItem_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();
|
||||
toolStripMenuItem_ManageResource = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Help = new ToolStripMenuItem();
|
||||
toolStripMenuItem_Diagnostics = new ToolStripMenuItem();
|
||||
toolStripSeparator3 = new ToolStripSeparator();
|
||||
toolStripMenuItem_About = new ToolStripMenuItem();
|
||||
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);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_MainForm).BeginInit();
|
||||
splitContainer_MainForm.Panel1.SuspendLayout();
|
||||
splitContainer_MainForm.Panel2.SuspendLayout();
|
||||
splitContainer_MainForm.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_Functional).BeginInit();
|
||||
splitContainer_Functional.Panel1.SuspendLayout();
|
||||
splitContainer_Functional.Panel2.SuspendLayout();
|
||||
splitContainer_Functional.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_Information).BeginInit();
|
||||
splitContainer_Information.Panel1.SuspendLayout();
|
||||
splitContainer_Information.Panel2.SuspendLayout();
|
||||
splitContainer_Information.SuspendLayout();
|
||||
groupBox_SkelList.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_Config).BeginInit();
|
||||
splitContainer_Config.Panel1.SuspendLayout();
|
||||
splitContainer_Config.Panel2.SuspendLayout();
|
||||
splitContainer_Config.SuspendLayout();
|
||||
groupBox_PreviewConfig.SuspendLayout();
|
||||
groupBox_SkelConfig.SuspendLayout();
|
||||
groupBox_Preview.SuspendLayout();
|
||||
menuStrip.SuspendLayout();
|
||||
panel_MainForm.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// splitContainer_MainForm
|
||||
//
|
||||
splitContainer_MainForm.Cursor = Cursors.SizeNS;
|
||||
resources.ApplyResources(splitContainer_MainForm, "splitContainer_MainForm");
|
||||
splitContainer_MainForm.FixedPanel = FixedPanel.Panel2;
|
||||
splitContainer_MainForm.Name = "splitContainer_MainForm";
|
||||
//
|
||||
// splitContainer_MainForm.Panel1
|
||||
//
|
||||
splitContainer_MainForm.Panel1.Controls.Add(splitContainer_Functional);
|
||||
splitContainer_MainForm.Panel1.Cursor = Cursors.Default;
|
||||
//
|
||||
// splitContainer_MainForm.Panel2
|
||||
//
|
||||
splitContainer_MainForm.Panel2.Controls.Add(rtbLog);
|
||||
splitContainer_MainForm.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_MainForm.TabStop = false;
|
||||
splitContainer_MainForm.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_MainForm.MouseUp += splitContainer_MouseUp;
|
||||
//
|
||||
// splitContainer_Functional
|
||||
//
|
||||
splitContainer_Functional.Cursor = Cursors.SizeWE;
|
||||
resources.ApplyResources(splitContainer_Functional, "splitContainer_Functional");
|
||||
splitContainer_Functional.FixedPanel = FixedPanel.Panel1;
|
||||
splitContainer_Functional.Name = "splitContainer_Functional";
|
||||
//
|
||||
// splitContainer_Functional.Panel1
|
||||
//
|
||||
splitContainer_Functional.Panel1.Controls.Add(splitContainer_Information);
|
||||
splitContainer_Functional.Panel1.Cursor = Cursors.Default;
|
||||
//
|
||||
// splitContainer_Functional.Panel2
|
||||
//
|
||||
splitContainer_Functional.Panel2.Controls.Add(groupBox_Preview);
|
||||
splitContainer_Functional.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_Functional.TabStop = false;
|
||||
splitContainer_Functional.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_Functional.MouseUp += splitContainer_MouseUp;
|
||||
//
|
||||
// splitContainer_Information
|
||||
//
|
||||
splitContainer_Information.Cursor = Cursors.SizeWE;
|
||||
resources.ApplyResources(splitContainer_Information, "splitContainer_Information");
|
||||
splitContainer_Information.Name = "splitContainer_Information";
|
||||
//
|
||||
// splitContainer_Information.Panel1
|
||||
//
|
||||
splitContainer_Information.Panel1.Controls.Add(groupBox_SkelList);
|
||||
splitContainer_Information.Panel1.Cursor = Cursors.Default;
|
||||
//
|
||||
// splitContainer_Information.Panel2
|
||||
//
|
||||
splitContainer_Information.Panel2.Controls.Add(splitContainer_Config);
|
||||
splitContainer_Information.Panel2.Cursor = Cursors.Default;
|
||||
splitContainer_Information.TabStop = false;
|
||||
splitContainer_Information.SplitterMoved += splitContainer_SplitterMoved;
|
||||
splitContainer_Information.MouseUp += splitContainer_MouseUp;
|
||||
//
|
||||
// groupBox_SkelList
|
||||
//
|
||||
groupBox_SkelList.Controls.Add(spineListView);
|
||||
resources.ApplyResources(groupBox_SkelList, "groupBox_SkelList");
|
||||
groupBox_SkelList.Name = "groupBox_SkelList";
|
||||
groupBox_SkelList.TabStop = false;
|
||||
//
|
||||
// spineListView
|
||||
//
|
||||
resources.ApplyResources(spineListView, "spineListView");
|
||||
spineListView.Name = "spineListView";
|
||||
spineListView.SpinePropertyGrid = spineViewPropertyGrid;
|
||||
//
|
||||
// spineViewPropertyGrid
|
||||
//
|
||||
resources.ApplyResources(spineViewPropertyGrid, "spineViewPropertyGrid");
|
||||
spineViewPropertyGrid.Name = "spineViewPropertyGrid";
|
||||
//
|
||||
// splitContainer_Config
|
||||
//
|
||||
resources.ApplyResources(splitContainer_Config, "splitContainer_Config");
|
||||
splitContainer_Config.Name = "splitContainer_Config";
|
||||
//
|
||||
// splitContainer_Config.Panel1
|
||||
//
|
||||
splitContainer_Config.Panel1.Controls.Add(groupBox_PreviewConfig);
|
||||
//
|
||||
// splitContainer_Config.Panel2
|
||||
//
|
||||
splitContainer_Config.Panel2.Controls.Add(groupBox_SkelConfig);
|
||||
//
|
||||
// groupBox_PreviewConfig
|
||||
//
|
||||
groupBox_PreviewConfig.Controls.Add(propertyGrid_Previewer);
|
||||
resources.ApplyResources(groupBox_PreviewConfig, "groupBox_PreviewConfig");
|
||||
groupBox_PreviewConfig.Name = "groupBox_PreviewConfig";
|
||||
groupBox_PreviewConfig.TabStop = false;
|
||||
//
|
||||
// propertyGrid_Previewer
|
||||
//
|
||||
resources.ApplyResources(propertyGrid_Previewer, "propertyGrid_Previewer");
|
||||
propertyGrid_Previewer.Name = "propertyGrid_Previewer";
|
||||
propertyGrid_Previewer.ToolbarVisible = false;
|
||||
//
|
||||
// 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(spinePreviewPanel);
|
||||
resources.ApplyResources(groupBox_Preview, "groupBox_Preview");
|
||||
groupBox_Preview.Name = "groupBox_Preview";
|
||||
groupBox_Preview.TabStop = false;
|
||||
//
|
||||
// spinePreviewPanel
|
||||
//
|
||||
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);
|
||||
resources.ApplyResources(panel_MainForm, "panel_MainForm");
|
||||
panel_MainForm.Name = "panel_MainForm";
|
||||
//
|
||||
// toolTip
|
||||
//
|
||||
toolTip.ShowAlways = true;
|
||||
//
|
||||
// SpineViewerForm
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
AutoScaleMode = AutoScaleMode.Dpi;
|
||||
Controls.Add(panel_MainForm);
|
||||
Controls.Add(menuStrip);
|
||||
MainMenuStrip = menuStrip;
|
||||
Name = "SpineViewerForm";
|
||||
FormClosing += MainForm_FormClosing;
|
||||
Load += MainForm_Load;
|
||||
splitContainer_MainForm.Panel1.ResumeLayout(false);
|
||||
splitContainer_MainForm.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_MainForm).EndInit();
|
||||
splitContainer_MainForm.ResumeLayout(false);
|
||||
splitContainer_Functional.Panel1.ResumeLayout(false);
|
||||
splitContainer_Functional.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_Functional).EndInit();
|
||||
splitContainer_Functional.ResumeLayout(false);
|
||||
splitContainer_Information.Panel1.ResumeLayout(false);
|
||||
splitContainer_Information.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_Information).EndInit();
|
||||
splitContainer_Information.ResumeLayout(false);
|
||||
groupBox_SkelList.ResumeLayout(false);
|
||||
splitContainer_Config.Panel1.ResumeLayout(false);
|
||||
splitContainer_Config.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)splitContainer_Config).EndInit();
|
||||
splitContainer_Config.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();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private MenuStrip menuStrip;
|
||||
private ToolStripMenuItem toolStripMenuItem_File;
|
||||
private ToolStripMenuItem toolStripMenuItem_Open;
|
||||
private ToolStripMenuItem toolStripMenuItem_Exit;
|
||||
private ToolStripSeparator toolStripSeparator1;
|
||||
private ToolStripSeparator toolStripSeparator2;
|
||||
private RichTextBox rtbLog;
|
||||
private SplitContainer splitContainer_MainForm;
|
||||
private SplitContainer splitContainer_Functional;
|
||||
private SplitContainer splitContainer_Information;
|
||||
private GroupBox groupBox_SkelList;
|
||||
private GroupBox groupBox_SkelConfig;
|
||||
private GroupBox groupBox_PreviewConfig;
|
||||
private Panel panel_MainForm;
|
||||
private ToolStripMenuItem toolStripMenuItem_Help;
|
||||
private ToolStripMenuItem toolStripMenuItem_About;
|
||||
private ToolStripMenuItem toolStripMenuItem_BatchOpen;
|
||||
private GroupBox groupBox_Preview;
|
||||
private ToolTip toolTip;
|
||||
private Controls.SpineListView spineListView;
|
||||
private PropertyGrid propertyGrid_Previewer;
|
||||
private Controls.SpinePreviewPanel spinePreviewPanel;
|
||||
private ToolStripMenuItem toolStripMenuItem_Diagnostics;
|
||||
private ToolStripSeparator toolStripSeparator3;
|
||||
private ToolStripMenuItem toolStripMenuItem_Download;
|
||||
private ToolStripMenuItem toolStripMenuItem_ManageResource;
|
||||
private ToolStripMenuItem toolStripMenuItem_Tool;
|
||||
private ToolStripMenuItem toolStripMenuItem_ConvertFileFormat;
|
||||
private ToolStripMenuItem toolStripMenuItem_Export;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportFrame;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportFrameSequence;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportGif;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportMp4;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportMov;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportMkv;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportWebm;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportCustom;
|
||||
private Controls.SpineViewPropertyGrid spineViewPropertyGrid;
|
||||
private ToolStripSeparator toolStripSeparator4;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportWebp;
|
||||
private ToolStripMenuItem toolStripMenuItem_ExportAvif;
|
||||
private ToolStripSeparator toolStripSeparator5;
|
||||
private ToolStripSeparator toolStripSeparator6;
|
||||
private SplitContainer splitContainer_Config;
|
||||
private ToolStripMenuItem toolStripMenuItem_Experiment;
|
||||
private ToolStripMenuItem toolStripMenuItem_DesktopProjection;
|
||||
private ToolStripMenuItem toolStripMenuItem_Debug;
|
||||
private ToolStripMenuItem ToolStripMenuItem_Language;
|
||||
private ToolStripMenuItem ToolStripMenuItem_English;
|
||||
private ToolStripMenuItem ToolStripMenuItem_Chinese;
|
||||
private ToolStripMenuItem toolStripMenuItem_Texture;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceSmooth;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceRepeated;
|
||||
private ToolStripMenuItem toolStripMenuItem_ForceMipmap;
|
||||
}
|
||||
}
|
||||
532
SpineViewer/Forms/SpineViewerForm.cs
Normal file
532
SpineViewer/Forms/SpineViewerForm.cs
Normal file
@@ -0,0 +1,532 @@
|
||||
using NLog;
|
||||
using SpineViewer.Spine;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using SpineViewer.Natives;
|
||||
using SpineViewer.Utils;
|
||||
using SpineViewer.Spine.SpineExporter;
|
||||
using System.Configuration;
|
||||
using SpineViewer.Utils.Localize;
|
||||
|
||||
namespace SpineViewer
|
||||
{
|
||||
internal partial class SpineViewerForm : Form
|
||||
{
|
||||
private readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly Dictionary<string, Exporter> exporterCache = [];
|
||||
|
||||
public SpineViewerForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeLogConfiguration();
|
||||
|
||||
// 执行一些初始化工作
|
||||
try
|
||||
{
|
||||
SFMLShader.Init();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex.ToString());
|
||||
logger.Error("Failed to load fragment shader");
|
||||
MessagePopup.Warn(Properties.Resources.failLoadingFragmentShader, Properties.Resources.msgBoxWarning);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
toolStripMenuItem_Debug.Visible = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化窗口日志器
|
||||
/// </summary>
|
||||
private void InitializeLogConfiguration()
|
||||
{
|
||||
// 窗口日志
|
||||
var rtbTarget = new NLog.Windows.Forms.RichTextBoxTarget
|
||||
{
|
||||
Name = "rtbTarget",
|
||||
TargetForm = this,
|
||||
TargetRichTextBox = rtbLog,
|
||||
AutoScroll = true,
|
||||
MaxLines = 3000,
|
||||
SupportLinks = true,
|
||||
Layout = "[${level:format=OneLetter}]${date:format=yyyy-MM-dd HH\\:mm\\:ss} - ${message}"
|
||||
};
|
||||
|
||||
rtbTarget.WordColoringRules.Add(new("[D]", "Gray", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[I]", "DimGray", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[W]", "DarkOrange", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[E]", "Red", "Empty", FontStyle.Bold));
|
||||
rtbTarget.WordColoringRules.Add(new("[F]", "DarkRed", "Empty", FontStyle.Bold));
|
||||
|
||||
LogManager.Configuration.AddTarget(rtbTarget);
|
||||
LogManager.Configuration.AddRule(LogLevel.Debug, LogLevel.Fatal, rtbTarget);
|
||||
LogManager.ReconfigExistingLoggers();
|
||||
}
|
||||
|
||||
private void MainForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
spinePreviewPanel.StartRender();
|
||||
string cultureName = ConfigurationManager.AppSettings["localize"];
|
||||
switch (cultureName)
|
||||
{
|
||||
case "zh-CN":
|
||||
ToolStripMenuItem_Chinese.Checked = true;
|
||||
ToolStripMenuItem_English.Checked = false;
|
||||
break;
|
||||
case "en-US":
|
||||
ToolStripMenuItem_English.Checked = true;
|
||||
ToolStripMenuItem_Chinese.Checked = false;
|
||||
break;
|
||||
default:
|
||||
ToolStripMenuItem_Chinese.Checked = true;
|
||||
ToolStripMenuItem_English.Checked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
spinePreviewPanel.StopRender();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Open_Click(object sender, EventArgs e)
|
||||
{
|
||||
spineListView.Add();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_BatchOpen_Click(object sender, EventArgs e)
|
||||
{
|
||||
spineListView.BatchAdd();
|
||||
}
|
||||
|
||||
#region private void toolStripMenuItem_ExportXXX_Click(object sender, EventArgs e)
|
||||
|
||||
private void toolStripMenuItem_ExportFrame_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (spinePreviewPanel.IsUpdating && MessagePopup.Quest(Properties.Resources.isUpdatingAndManuallyExportFrame, Properties.Resources.msgBoxQuest) != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var k = nameof(toolStripMenuItem_ExportFrame);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new FrameExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new FrameExporterProperty((FrameExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportFrameSequence_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportFrameSequence);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new FrameSequenceExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new FrameSequenceExporterProperty((FrameSequenceExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportGif_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportGif);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new GifExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new GifExporterProperty((GifExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportWebp_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportWebp);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new WebpExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new WebpExporterProperty((WebpExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportAvif_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportAvif);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new AvifExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new AvifExporterProperty((AvifExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportMp4_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportMp4);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new Mp4Exporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new Mp4ExporterProperty((Mp4Exporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportWebm_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportWebm);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new WebmExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new WebmExporterProperty((WebmExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportMkv_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportMkv);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new MkvExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new MkvExporterProperty((MkvExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportMov_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportMov);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new MovExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new MovExporterProperty((MovExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ExportCustom_Click(object sender, EventArgs e)
|
||||
{
|
||||
var k = nameof(toolStripMenuItem_ExportCustom);
|
||||
if (!exporterCache.ContainsKey(k)) exporterCache[k] = new CustomExporter();
|
||||
|
||||
var exporter = exporterCache[k];
|
||||
using var view = spinePreviewPanel.GetView();
|
||||
exporter.Resolution = spinePreviewPanel.Resolution;
|
||||
exporter.PreviewerView = view;
|
||||
exporter.RenderSelectedOnly = spinePreviewPanel.RenderSelectedOnly;
|
||||
|
||||
var exportDialog = new Dialogs.ExportDialog(new CustomExporterProperty((CustomExporter)exporter));
|
||||
if (exportDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += Export_Work;
|
||||
progressDialog.RunWorkerAsync(exporter);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void toolStripMenuItem_Exit_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ForceSmooth_Click(object sender, EventArgs e)
|
||||
{
|
||||
SpineObject.TextureLoader.ForceSmooth = !toolStripMenuItem_ForceSmooth.Checked;
|
||||
toolStripMenuItem_ForceSmooth.Checked = SpineObject.TextureLoader.ForceSmooth;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ForceRepeated_Click(object sender, EventArgs e)
|
||||
{
|
||||
SpineObject.TextureLoader.ForceRepeated = !toolStripMenuItem_ForceRepeated.Checked;
|
||||
toolStripMenuItem_ForceRepeated.Checked = SpineObject.TextureLoader.ForceRepeated;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ForceMipmap_Click(object sender, EventArgs e)
|
||||
{
|
||||
SpineObject.TextureLoader.ForceMipmap = !toolStripMenuItem_ForceMipmap.Checked;
|
||||
toolStripMenuItem_ForceMipmap.Checked = SpineObject.TextureLoader.ForceMipmap;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ConvertFileFormat_Click(object sender, EventArgs e)
|
||||
{
|
||||
var openDialog = new Dialogs.ConvertFileFormatDialog();
|
||||
if (openDialog.ShowDialog() != DialogResult.OK)
|
||||
return;
|
||||
|
||||
var progressDialog = new Dialogs.ProgressDialog();
|
||||
progressDialog.DoWork += ConvertFileFormat_Work;
|
||||
progressDialog.RunWorkerAsync(openDialog.Result);
|
||||
progressDialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_ManageResource_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_About_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var dialog = new Dialogs.AboutDialog();
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Diagnostics_Click(object sender, EventArgs e)
|
||||
{
|
||||
using var dialog = new Dialogs.DiagnosticsDialog();
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
private void splitContainer_SplitterMoved(object sender, SplitterEventArgs e) => ActiveControl = null;
|
||||
|
||||
private void splitContainer_MouseUp(object sender, MouseEventArgs e) => ActiveControl = null;
|
||||
|
||||
private void Export_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = (BackgroundWorker)sender;
|
||||
var exporter = (Exporter)e.Argument;
|
||||
Invoke(() => TaskbarManager.SetProgressState(Handle, TBPFLAG.TBPF_INDETERMINATE));
|
||||
spinePreviewPanel.StopRender();
|
||||
lock (spineListView.Spines) { exporter.Export(spineListView.Spines.Where(sp => !sp.IsHidden).ToArray(), (BackgroundWorker)sender); }
|
||||
e.Cancel = worker.CancellationPending;
|
||||
spinePreviewPanel.StartRender();
|
||||
Invoke(() => TaskbarManager.SetProgressState(Handle, TBPFLAG.TBPF_NOPROGRESS));
|
||||
}
|
||||
|
||||
private void ConvertFileFormat_Work(object? sender, DoWorkEventArgs e)
|
||||
{
|
||||
var worker = sender as BackgroundWorker;
|
||||
var args = e.Argument as Dialogs.ConvertFileFormatDialogResult;
|
||||
var newSuffix = args.JsonTarget ? ".json" : ".skel";
|
||||
|
||||
int totalCount = args.SkelPaths.Length;
|
||||
int success = 0;
|
||||
int error = 0;
|
||||
|
||||
SkeletonConverter srcCvter = args.SourceVersion != SpineVersion.Auto ? SkeletonConverter.New(args.SourceVersion) : null;
|
||||
SkeletonConverter tgtCvter = SkeletonConverter.New(args.TargetVersion);
|
||||
|
||||
worker.ReportProgress(0, $"{Properties.Resources.process} 0/{totalCount}");
|
||||
for (int i = 0; i < totalCount; i++)
|
||||
{
|
||||
if (worker.CancellationPending)
|
||||
{
|
||||
e.Cancel = true;
|
||||
break;
|
||||
}
|
||||
|
||||
var skelPath = args.SkelPaths[i];
|
||||
var newPath = Path.ChangeExtension(skelPath, newSuffix);
|
||||
if (args.OutputDir is string outputDir) newPath = Path.Combine(outputDir, Path.GetFileName(newPath));
|
||||
|
||||
try
|
||||
{
|
||||
if (args.SourceVersion == SpineVersion.Auto)
|
||||
{
|
||||
try
|
||||
{
|
||||
srcCvter = SkeletonConverter.New(SpineUtils.GetVersion(skelPath));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidDataException($"Auto version detection failed for {skelPath}, try to use a specific version", ex);
|
||||
}
|
||||
}
|
||||
var root = srcCvter.Read(skelPath);
|
||||
root = srcCvter.ToVersion(root, args.TargetVersion);
|
||||
if (args.JsonTarget) tgtCvter.WriteJson(root, newPath);
|
||||
else tgtCvter.WriteBinary(root, newPath);
|
||||
success++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex.ToString());
|
||||
logger.Error("Failed to convert {}", skelPath);
|
||||
error++;
|
||||
}
|
||||
|
||||
worker.ReportProgress((int)((i + 1) * 100.0) / totalCount, $"{Properties.Resources.process} {i + 1}/{totalCount}");
|
||||
}
|
||||
|
||||
if (error > 0)
|
||||
{
|
||||
logger.Warn("Batch convert {} successfully, {} failed", success, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Info("{} skel converted successfully", success);
|
||||
}
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_DesktopProjection_Click(object sender, EventArgs e)
|
||||
{
|
||||
toolStripMenuItem_DesktopProjection.Checked = !toolStripMenuItem_DesktopProjection.Checked;
|
||||
spinePreviewPanel.EnableDesktopProjection = toolStripMenuItem_DesktopProjection.Checked;
|
||||
}
|
||||
|
||||
private void toolStripMenuItem_Debug_Click(object sender, EventArgs e)
|
||||
{
|
||||
#if DEBUG
|
||||
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
||||
//var root = cvt.ReadBinary(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3 - 副本.skel");
|
||||
//cvt.WriteJson(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
||||
|
||||
//root = cvt.ReadJson(@"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.json");
|
||||
//cvt.WriteBinary(root, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
||||
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\AzurLane_Export\AzurLane_Dynamic\docs\aerhangeersike\aerhangeersike_3\aerhangeersike_3.skel");
|
||||
|
||||
//var cvt = SkeletonConverter.New(SpineVersion.V38);
|
||||
//var root = cvt.ReadJson(@"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.json");
|
||||
//cvt.WriteBinary(root, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
||||
//var sp = SpineObject.New(SpineVersion.V38, @"D:\ACGN\G\GirlsCreation\standing_spine\st4020069\st4020069.skel");
|
||||
//_Test();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void ToolStripMenuItem_English_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (ToolStripMenuItem_English.Checked) return;
|
||||
ChangeLanguage("en-US");
|
||||
}
|
||||
|
||||
private void ToolStripMenuItem_Chinese_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (ToolStripMenuItem_Chinese.Checked) return;
|
||||
ChangeLanguage("zh-CN");
|
||||
}
|
||||
|
||||
private void ChangeLanguage(string localize)
|
||||
{
|
||||
DialogResult result = MessageBox.Show(
|
||||
Properties.Resources.restartPrompt,
|
||||
Properties.Resources.restartTitle,
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Question);
|
||||
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
LocalizeConfiguration.UpdateLocalizeSetting(localize);
|
||||
LocalizeConfiguration.SetCulture();
|
||||
Application.Restart();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
//private void spinePreviewer_KeyDown(object sender, KeyEventArgs e)
|
||||
//{
|
||||
// switch (e.KeyCode)
|
||||
// {
|
||||
// case Keys.Space:
|
||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||
// spinePreviewer.ClickStopButton();
|
||||
// else
|
||||
// spinePreviewer.ClickStartButton();
|
||||
// break;
|
||||
// case Keys.Right:
|
||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||
// spinePreviewer.ClickForwardFastButton();
|
||||
// else
|
||||
// spinePreviewer.ClickForwardStepButton();
|
||||
// break;
|
||||
// case Keys.Left:
|
||||
// if ((ModifierKeys & Keys.Alt) != 0)
|
||||
// spinePreviewer.ClickRestartButton();
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
3562
SpineViewer/Forms/SpineViewerForm.en.resx
Normal file
3562
SpineViewer/Forms/SpineViewerForm.en.resx
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user