Compare commits
579 Commits
mac_change
...
sdl_mac_fi
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e969649ae | |||
| 3288fe4006 | |||
| fd334769b2 | |||
| 576130f74f | |||
| b99c8ddda7 | |||
|
|
2fc95bdf57 | ||
|
|
9a7abd751f | ||
|
|
cabae8142d | ||
|
|
2d0da37907 | ||
|
|
42ec33bd9a | ||
|
|
806027408a | ||
|
|
dc6d53de7c | ||
|
|
70f2eee172 | ||
|
|
7737dbc77f | ||
|
|
9d9d582598 | ||
|
|
f1796dc8c8 | ||
|
|
ebb4ff1dc2 | ||
|
|
ea5e7f1416 | ||
|
|
917e62621d | ||
|
|
a88e3265cd | ||
|
|
b2d1d0f1d9 | ||
|
|
c6204fc274 | ||
|
|
8b383d4dbe | ||
|
|
7b695bf6bf | ||
|
|
327547a895 | ||
|
|
e2fbd83086 | ||
|
|
d96e1297f7 | ||
|
|
2748216190 | ||
|
|
b2457b6ee6 | ||
|
|
bf20f5d2bf | ||
|
|
767854a2af | ||
|
|
243173df3c | ||
|
|
408c6d96b1 | ||
|
|
039407b6ee | ||
|
|
71ff0c6362 | ||
|
|
b3aeab777f | ||
|
|
b8110e9db3 | ||
|
|
f500fcd6fd | ||
|
|
bda0dee371 | ||
|
|
ec756fe626 | ||
|
|
b78ff57f6a | ||
|
|
9fa9e75e08 | ||
|
|
095f7277e2 | ||
|
|
f26dbf530c | ||
|
|
76378156f7 | ||
|
|
c12948c6cc | ||
|
|
e99dc8dce4 | ||
|
|
258ba233d5 | ||
|
|
2b538e4864 | ||
|
|
a0dc300a7b | ||
|
|
9f54bca831 | ||
|
|
bb2ee7260f | ||
|
|
1bef4d00ad | ||
|
|
81176c98a1 | ||
|
|
6c4fc44163 | ||
|
|
a41f2e9260 | ||
|
|
cc9e41fe44 | ||
|
|
4d77ced41d | ||
|
|
54202eeb8a | ||
|
|
0e1c5cd6f8 | ||
|
|
8f50d9faec | ||
|
|
5249864af4 | ||
|
|
3e5ceb1e1e | ||
|
|
ed46025a11 | ||
|
|
706b24e1c8 | ||
|
|
f5651de725 | ||
|
|
51ff2969e1 | ||
|
|
5773dc47f4 | ||
|
|
c30c56e8eb | ||
|
|
eab7794e3b | ||
|
|
b347cd2f54 | ||
|
|
78052fbaec | ||
|
|
557dc9b649 | ||
|
|
9fbcce13b3 | ||
|
|
6d433d4ef7 | ||
|
|
7531b1fdbd | ||
|
|
58586ca4f0 | ||
|
|
09a0573932 | ||
|
|
b6789ee523 | ||
|
|
f1b6c13ba9 | ||
|
|
ccc8d209da | ||
|
|
e624e1ba69 | ||
|
|
d0cc88f82a | ||
|
|
a48ce78733 | ||
|
|
d1f6440a76 | ||
|
|
5ccc33719e | ||
|
|
0f09cad1cf | ||
|
|
f92ec30e1b | ||
|
|
a9fbbaa88e | ||
|
|
3db3eb58a3 | ||
|
|
e455c874c6 | ||
|
|
32af903a2d | ||
|
|
c12553812c | ||
|
|
c9df03d293 | ||
|
|
c71e1d78e0 | ||
|
|
a84109df2c | ||
|
|
9d0e4e9768 | ||
|
|
3f2e6d82c9 | ||
|
|
56b208ad85 | ||
|
|
842b25f80f | ||
|
|
27a1db617c | ||
|
|
8356009526 | ||
|
|
0cbb2f0525 | ||
|
|
0ac5e85cd9 | ||
|
|
9b5dbe858c | ||
|
|
914e0869b1 | ||
|
|
2c742bee41 | ||
|
|
a9ac4d427f | ||
|
|
0f332e331d | ||
|
|
be69453bfd | ||
|
|
5e6723aa22 | ||
|
|
c7449c8f95 | ||
|
|
e23cbd1de9 | ||
|
|
0fe297c390 | ||
|
|
b10303cd8d | ||
|
|
9e9715a2ea | ||
|
|
a04995174f | ||
|
|
e4a97258f3 | ||
|
|
912f5fb4f3 | ||
|
|
4d9898770a | ||
|
|
508ccb714c | ||
|
|
0c1da8e13b | ||
|
|
d40573df5b | ||
|
|
707d19284d | ||
|
|
5a6b07e4c5 | ||
|
|
935645d553 | ||
|
|
d9f2931b9e | ||
|
|
0770f4a216 | ||
|
|
ecc9406968 | ||
|
|
d06be3d1d6 | ||
|
|
aeecadffb0 | ||
|
|
f3e23b6420 | ||
|
|
7c5b1942e6 | ||
|
|
9850761b5c | ||
|
|
1e1f7ce56d | ||
|
|
64005c2774 | ||
|
|
22ad2d1fab | ||
|
|
9d478b570f | ||
|
|
35fb320ff0 | ||
|
|
e000a6727e | ||
|
|
3a3b997e97 | ||
|
|
f3c957481c | ||
|
|
e8134803c4 | ||
|
|
7b3cfd989f | ||
|
|
13f5222ec7 | ||
|
|
29abfbcdc9 | ||
|
|
a63e05d444 | ||
|
|
f0f1c57ff1 | ||
|
|
d2ef0671e3 | ||
|
|
5383de10b8 | ||
|
|
1318dde3ca | ||
|
|
90e96678a6 | ||
|
|
2e13c6043d | ||
|
|
32d0241f54 | ||
|
|
e8fe1cd044 | ||
|
|
956a9b8fab | ||
|
|
5732290c29 | ||
|
|
601b40dd86 | ||
|
|
7f1add4bdd | ||
|
|
fa17d83501 | ||
|
|
99d3da467e | ||
|
|
b54794255a | ||
|
|
ce5dd6bc16 | ||
|
|
45feda8f07 | ||
|
|
bd4c20d9ce | ||
|
|
cc89a1e1ca | ||
|
|
df6b550c3d | ||
|
|
0cb5e3421a | ||
|
|
4d5bf4ec0c | ||
|
|
88fe9ba186 | ||
|
|
b756c16018 | ||
|
|
1e44bb1832 | ||
|
|
3baec506e2 | ||
|
|
90a0cc0e03 | ||
|
|
a346e258d3 | ||
|
|
c673e9f52d | ||
|
|
1bd86ca28b | ||
|
|
4594a84753 | ||
|
|
a1af870874 | ||
|
|
b8d5ea595e | ||
|
|
5404dff5c2 | ||
|
|
a5ec8565e4 | ||
|
|
e5d526c9af | ||
|
|
cb9e09c21b | ||
|
|
750fd1f941 | ||
|
|
1308465280 | ||
|
|
a38633c453 | ||
|
|
3949cba83c | ||
|
|
e10d784e83 | ||
|
|
0f5c5dcf3e | ||
|
|
ed3a827b5f | ||
|
|
7f49cae9af | ||
|
|
427f4647fc | ||
|
|
d5d10aa329 | ||
|
|
5b2b1930d2 | ||
|
|
5655cc8f42 | ||
|
|
8bad080d59 | ||
|
|
0237235dcb | ||
|
|
a5bbf0dbde | ||
|
|
5ec018b904 | ||
|
|
f2a13b64d4 | ||
|
|
44ecac7ffc | ||
|
|
60076d48c7 | ||
|
|
2fbeac6077 | ||
|
|
57355a741e | ||
|
|
14d6273a2f | ||
|
|
0cec65f35f | ||
|
|
fcdd05dede | ||
|
|
e008c7e2b4 | ||
|
|
f42a9a760a | ||
|
|
80767d65ae | ||
|
|
21b2e59fbb | ||
|
|
5fb1ad078b | ||
|
|
1fc5316d12 | ||
|
|
1ceb781903 | ||
|
|
d3891688f0 | ||
|
|
f876068086 | ||
|
|
6ae68bc6cc | ||
|
|
a8e7faec3c | ||
|
|
ab6e291976 | ||
|
|
2cb12e3c0f | ||
|
|
c91c209974 | ||
|
|
45a8d82a83 | ||
|
|
b41d25cbce | ||
|
|
3d201ec73f | ||
|
|
fa91e3e3ab | ||
|
|
38c87c158a | ||
|
|
241d37130a | ||
|
|
21981f666f | ||
|
|
afe917a7f3 | ||
|
|
d2a03b90ec | ||
|
|
88587fb6a4 | ||
|
|
895758d27d | ||
|
|
48d86ac7ae | ||
|
|
bc3cddc774 | ||
|
|
d784fddf95 | ||
|
|
fc7abbf541 | ||
|
|
8b4f8de988 | ||
|
|
549ed76e7c | ||
|
|
e7016564b1 | ||
|
|
8318a9c1d0 | ||
|
|
6b1490dac4 | ||
|
|
5c51652e16 | ||
|
|
6736f2f77a | ||
|
|
ab685ccc8c | ||
|
|
b5d841ffc9 | ||
|
|
cb17bcd2ff | ||
|
|
f17b7b3c79 | ||
|
|
1374a0440b | ||
|
|
7fa40eba83 | ||
|
|
62e492452d | ||
|
|
30d7588d9c | ||
|
|
e736048fab | ||
|
|
14e59281e4 | ||
|
|
895dcf4aa6 | ||
|
|
6d9d606085 | ||
|
|
a94b9f9426 | ||
|
|
ace84ae29f | ||
|
|
22c88eb59d | ||
|
|
96bbae8e28 | ||
|
|
479c5f896c | ||
|
|
0d3642f39d | ||
|
|
e47e1998a1 | ||
|
|
62492c7607 | ||
|
|
c3aecc1a11 | ||
|
|
6629ead842 | ||
|
|
14dd70fb3d | ||
|
|
2000a95fa7 | ||
|
|
68ac2f4c79 | ||
|
|
05aaf0dc99 | ||
|
|
f33db8647a | ||
|
|
0ade65036e | ||
|
|
b8bb40fcf8 | ||
|
|
0d133cfbdc | ||
|
|
337fea0f69 | ||
|
|
ee23196548 | ||
|
|
394dc31bb0 | ||
|
|
deadb6f6d0 | ||
|
|
a6c6be9c2e | ||
|
|
93a38566ea | ||
|
|
2a2f046f30 | ||
|
|
73b4b0dcee | ||
|
|
b930ae0ca9 | ||
|
|
8cdb6d77ab | ||
|
|
afc4d0f3d3 | ||
|
|
3bbaa7025a | ||
|
|
5509bc4989 | ||
|
|
3cfa110a48 | ||
|
|
1ab3917332 | ||
|
|
2fb1e5bef7 | ||
|
|
a4cb839c6f | ||
|
|
3b1960b977 | ||
|
|
116f15f4ae | ||
|
|
a0bb8efc2b | ||
|
|
90ffc4e5f9 | ||
|
|
bf11575346 | ||
|
|
8dc8371a7f | ||
|
|
ee38f88562 | ||
|
|
e90de5d815 | ||
|
|
7fe7a8dd0e | ||
|
|
8afc25b19c | ||
|
|
37a39e750f | ||
|
|
59a9137a54 | ||
|
|
f4c1e81f64 | ||
|
|
7391af1c37 | ||
|
|
c376f220ca | ||
|
|
5ce0a1535f | ||
|
|
06bf9def8e | ||
|
|
57489abc3a | ||
|
|
200aca93d3 | ||
|
|
f8eae517f0 | ||
|
|
3a651bc660 | ||
|
|
4b7828f686 | ||
|
|
befb74297a | ||
|
|
c0e16cd34a | ||
|
|
e710a6e2d1 | ||
|
|
c378cd1d47 | ||
|
|
cd74b300f1 | ||
|
|
26cd07933e | ||
|
|
c4342b0a20 | ||
|
|
3038c56af4 | ||
|
|
3dc3e25649 | ||
|
|
e7071fbe43 | ||
|
|
01670ec6ae | ||
|
|
4d4571ee55 | ||
|
|
83bbb4f6ba | ||
|
|
a406d6dba2 | ||
|
|
72bd624384 | ||
|
|
82a02698df | ||
|
|
befac36a4f | ||
|
|
1282dffca9 | ||
|
|
b291cd93c3 | ||
|
|
28257296b9 | ||
|
|
164e380672 | ||
|
|
438a9e4c3d | ||
|
|
5942209114 | ||
|
|
06788055fe | ||
|
|
26838609db | ||
|
|
b408a8ce21 | ||
|
|
6fcc963cf6 | ||
|
|
0fa3472f24 | ||
|
|
c0056f3d9d | ||
|
|
b8fcb51aa3 | ||
|
|
341dc08f7c | ||
|
|
f0873411df | ||
|
|
94789712e8 | ||
|
|
d163064f95 | ||
|
|
64c2d64d84 | ||
|
|
a9c510c296 | ||
|
|
1ef35c3f94 | ||
|
|
23c3edcab9 | ||
|
|
2c98d80506 | ||
|
|
ac36840037 | ||
|
|
dfdcd47ad7 | ||
|
|
414c650550 | ||
|
|
2d9ca4c335 | ||
|
|
6c19996f95 | ||
|
|
377d5c00aa | ||
|
|
93ca9f1cb0 | ||
|
|
c62b3f7624 | ||
|
|
5fb9cf3be1 | ||
|
|
ceebc68d18 | ||
|
|
66b4c64f98 | ||
|
|
aff8090adb | ||
|
|
cee1b72f2f | ||
|
|
b9b11b3c2a | ||
|
|
feca1c7994 | ||
|
|
bd39e449d7 | ||
|
|
836e1d4f39 | ||
|
|
792393345d | ||
|
|
66be7ebc50 | ||
|
|
f8b161c04e | ||
|
|
bac361baf6 | ||
|
|
10bcf9c9a3 | ||
|
|
075727ab53 | ||
|
|
5a4e94d263 | ||
|
|
ad3c2be510 | ||
|
|
5641bf63e8 | ||
|
|
79a17d8fe3 | ||
|
|
6814a43418 | ||
|
|
6891256afe | ||
|
|
17b097b1a3 | ||
|
|
a96c7e631e | ||
|
|
9df5da2a88 | ||
|
|
3e63551e90 | ||
|
|
2a426e2812 | ||
|
|
c4f4983f6d | ||
|
|
a925c7410a | ||
|
|
f7e2f3a4d5 | ||
|
|
b1befacb84 | ||
|
|
23ebb0e754 | ||
| 5f9e8dedec | |||
|
|
3b2015e816 | ||
|
|
f1e851e1b8 | ||
|
|
b191d3918e | ||
|
|
db46050b16 | ||
|
|
24a11ac2a8 | ||
|
|
1cf69361a1 | ||
|
|
689fab2ba4 | ||
|
|
b36c757753 | ||
|
|
63f19aa4d6 | ||
|
|
8728d88dde | ||
|
|
f6888b099e | ||
|
|
239ceb75a9 | ||
|
|
20c9ed27fb | ||
|
|
ac4526744a | ||
|
|
d2a8ac54cf | ||
|
|
153b16ebd7 | ||
|
|
b535791c66 | ||
|
|
6ed7e8fa40 | ||
|
|
9d95bbaa8c | ||
|
|
e41ec4ebfd | ||
|
|
195d5b1aa2 | ||
|
|
7ea3fb1500 | ||
|
|
9be8589437 | ||
|
|
ff81d339ef | ||
|
|
7858225565 | ||
|
|
83bd1deafd | ||
|
|
9158e1c270 | ||
|
|
f0d182771d | ||
|
|
6081ed35bc | ||
|
|
4ca10c7869 | ||
|
|
9fc31b1021 | ||
|
|
366a5162b7 | ||
|
|
6fd58c418e | ||
|
|
08d9ae0ae6 | ||
|
|
27eb53e1a1 | ||
|
|
31b5685251 | ||
|
|
894cf2c886 | ||
|
|
5b3079acde | ||
|
|
0f49503abd | ||
|
|
be4e1edc3e | ||
|
|
1982694ef0 | ||
|
|
8b475e9f54 | ||
|
|
2b546eb4b3 | ||
|
|
69cefb6822 | ||
|
|
9772227146 | ||
|
|
34bddc7db1 | ||
|
|
7ff4ce18ff | ||
|
|
6e7a7c9350 | ||
|
|
2a9c6bbd1d | ||
|
|
0835a6559c | ||
|
|
489c4a3661 | ||
|
|
43dca143fa | ||
|
|
6bd13feba6 | ||
|
|
d1557e5292 | ||
|
|
c9fbafe014 | ||
|
|
0612b923e1 | ||
|
|
6f13a33be2 | ||
|
|
4ccf969f7a | ||
|
|
3d206e06d0 | ||
|
|
25e90deed6 | ||
|
|
7bc687194f | ||
|
|
d3bd377264 | ||
|
|
974c55418b | ||
|
|
0870a86a3a | ||
|
|
dd2e2c5b3a | ||
|
|
75a1b14beb | ||
|
|
8a760dc1e2 | ||
|
|
fc0b885a14 | ||
|
|
f12ad5c874 | ||
|
|
fd0584b406 | ||
|
|
374f6e40bb | ||
|
|
9c9e17a9d9 | ||
|
|
865a26cbbe | ||
|
|
56e825cad4 | ||
|
|
1df608e902 | ||
|
|
c631c37a34 | ||
|
|
07b6d3558a | ||
|
|
2a21141dd4 | ||
|
|
eac9f67bc1 | ||
|
|
b19611e3d2 | ||
|
|
37e776e407 | ||
|
|
05a0a6b539 | ||
|
|
3adda3629e | ||
|
|
a57fe6c04d | ||
|
|
29b043342a | ||
|
|
8d8bf87c69 | ||
|
|
ca54313bd8 | ||
|
|
7a96c1ff76 | ||
|
|
83c15c05bb | ||
|
|
ab88a6339a | ||
|
|
b27e556363 | ||
|
|
b0a0c5b66c | ||
|
|
f1d5c0257f | ||
|
|
ae46520edf | ||
|
|
5d9d64e6e7 | ||
|
|
4e8f54bb61 | ||
|
|
0eac545271 | ||
|
|
ec0877004c | ||
|
|
b171071893 | ||
|
|
91fd32b708 | ||
|
|
3279016067 | ||
|
|
a92d2b6ca2 | ||
|
|
a98a76f6e5 | ||
|
|
564c9ff0ca | ||
|
|
21d46dad07 | ||
| 71b222e0b0 | |||
| 5921f60af2 | |||
| 39269583c3 | |||
| cba3899c62 | |||
|
|
cfda18ea9d | ||
|
|
31b1ceb9f0 | ||
|
|
d3d67fddcc | ||
|
|
e272870803 | ||
|
|
d8c90184b9 | ||
|
|
5b1ca13225 | ||
|
|
0d8ac5b7ac | ||
|
|
b714668f4c | ||
| f6e9cf644a | |||
| 604bfb5fe6 | |||
| b3ea47b989 | |||
| 5d368e59a0 | |||
| 3afd3ce2d5 | |||
|
|
1b9f6ed20f | ||
|
|
2c5cc7fcc0 | ||
|
|
b9f177d1ab | ||
|
|
9708601d3b | ||
|
|
d671f57952 | ||
|
|
56e6df261d | ||
|
|
88b02105b3 | ||
|
|
0094216ff8 | ||
|
|
298ee284e1 | ||
|
|
7f2f73afd8 | ||
| 9f8b15f0d5 | |||
|
|
bb2e22ecf2 | ||
|
|
b5b1d84b3f | ||
|
|
4b62395d69 | ||
|
|
bbaa2dfc73 | ||
|
|
ab22b88a53 | ||
|
|
206b948ee1 | ||
|
|
fbad6ba75c | ||
|
|
bf3403449d | ||
|
|
d13b98b205 | ||
|
|
1188150163 | ||
|
|
e78191cc82 | ||
|
|
eb978c767e | ||
|
|
661dc8ea1c | ||
|
|
b6696564f5 | ||
|
|
316e5b2845 | ||
|
|
c1738bcb0a | ||
|
|
7b3e41efae | ||
|
|
3cef8cfd61 | ||
|
|
09964df198 | ||
|
|
dd8e6bf694 | ||
|
|
58cd3e82f6 | ||
|
|
5dd9171316 | ||
|
|
d6b1478bf1 | ||
|
|
e5bd90f58b | ||
|
|
d1972a56e2 | ||
|
|
69a7e1f25c | ||
|
|
b43ed886b9 | ||
|
|
18a0e8d612 | ||
|
|
ec08a6ca72 | ||
|
|
7b7d7aaf3d | ||
|
|
2d4843b1f4 | ||
|
|
7ba01a413f | ||
|
|
2516820e4a | ||
|
|
0917a743cd | ||
|
|
1dd96ae9cb | ||
|
|
07c1dfc613 | ||
|
|
fb5cedc575 | ||
|
|
05f08db66e | ||
|
|
52ee8b3953 | ||
|
|
a8768f918e | ||
|
|
e52b7170ce | ||
|
|
dd7233aaf7 | ||
|
|
cd0878f810 | ||
|
|
f588d6da51 | ||
|
|
9a363e2882 | ||
|
|
2901e3898c | ||
|
|
c63200cba0 | ||
|
|
c8a02ac607 | ||
|
|
09a304c214 | ||
|
|
4bacceb19f | ||
|
|
846065007b | ||
|
|
c45cba18a6 | ||
|
|
fccd43502b | ||
|
|
d2dba124df |
8
.github/ISSUE_TEMPLATE/1-bug.yaml
vendored
8
.github/ISSUE_TEMPLATE/1-bug.yaml
vendored
@@ -5,7 +5,7 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Thanks for taking the time to fill out this bug report! Please attach any minimal reproduction projects!
|
Thanks for taking the time to fill out this bug report! Please attach a minimal reproduction project if available!
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: description-area
|
id: description-area
|
||||||
attributes:
|
attributes:
|
||||||
@@ -17,19 +17,19 @@ body:
|
|||||||
id: steps-area
|
id: steps-area
|
||||||
attributes:
|
attributes:
|
||||||
label: Steps to reproduce
|
label: Steps to reproduce
|
||||||
description: Please provide reproduction steps if possible.
|
description: Please provide reproduction steps if available.
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
id: version
|
id: version
|
||||||
attributes:
|
attributes:
|
||||||
label: Version
|
label: Version
|
||||||
description: What version of Flax are you running?
|
description: What version of Flax did you experience the bug in?
|
||||||
options:
|
options:
|
||||||
- '1.8'
|
|
||||||
- '1.9'
|
- '1.9'
|
||||||
- '1.10'
|
- '1.10'
|
||||||
- '1.11'
|
- '1.11'
|
||||||
|
- '1.12'
|
||||||
- master branch
|
- master branch
|
||||||
default: 3
|
default: 3
|
||||||
validations:
|
validations:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ body:
|
|||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
Thanks for taking the time to fill out a feature request!
|
Thank you for taking the time to submit this feature request!
|
||||||
- type: textarea
|
- type: textarea
|
||||||
id: description-area
|
id: description-area
|
||||||
attributes:
|
attributes:
|
||||||
@@ -17,6 +17,6 @@ body:
|
|||||||
id: benefits-area
|
id: benefits-area
|
||||||
attributes:
|
attributes:
|
||||||
label: Benefits
|
label: Benefits
|
||||||
description: Please provide what benefits this feature would provide to the engine!
|
description: Please list what benefits this feature would provide to the engine!
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
18
.github/data/bt.sh
vendored
Normal file
18
.github/data/bt.sh
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# https://gist.github.com/ongardie/aa15f1f0d0e6b59890a9
|
||||||
|
gdb -q --batch \
|
||||||
|
-ex 'handle SIGHUP nostop pass' \
|
||||||
|
-ex 'handle SIGQUIT nostop pass' \
|
||||||
|
-ex 'handle SIGPIPE nostop pass' \
|
||||||
|
-ex 'handle SIGALRM nostop pass' \
|
||||||
|
-ex 'handle SIGTERM nostop pass' \
|
||||||
|
-ex 'handle SIGUSR1 nostop pass' \
|
||||||
|
-ex 'handle SIGUSR2 nostop pass' \
|
||||||
|
-ex 'handle SIGCHLD nostop pass' \
|
||||||
|
-ex 'handle SIG34 nostop pass' \
|
||||||
|
-ex 'set print thread-events off' \
|
||||||
|
-return-child-result \
|
||||||
|
-ex 'run' \
|
||||||
|
-ex 'thread apply all bt' \
|
||||||
|
--tty=/dev/stdout \
|
||||||
|
--args $*
|
||||||
6
.github/workflows/build_android.yml
vendored
6
.github/workflows/build_android.yml
vendored
@@ -4,6 +4,7 @@ on: [push, pull_request]
|
|||||||
env:
|
env:
|
||||||
DOTNET_NOLOGO: true
|
DOTNET_NOLOGO: true
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
DOTNET_ROLL_FORWARD: 'minor'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.419
|
||||||
- name: Setup .NET Workload
|
- name: Setup .NET Workload
|
||||||
run: |
|
run: |
|
||||||
dotnet workload install android
|
dotnet workload install android
|
||||||
@@ -33,4 +34,7 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
PowerShell "(Get-Content global.json).Replace('latestMajor', 'minor') | Set-Content global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/global.json).Replace('latestMajor', 'minor') | Set-Content Source/Tools/Flax.Build/global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/Flax.Build.csproj).Replace('LatestMajor', 'Minor') | Set-Content Source/Tools/Flax.Build/Flax.Build.csproj"
|
||||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=8 -arch=ARM64 -platform=Android -configuration=Release -buildtargets=FlaxGame
|
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=8 -arch=ARM64 -platform=Android -configuration=Release -buildtargets=FlaxGame
|
||||||
|
|||||||
3
.github/workflows/build_linux.yml
vendored
3
.github/workflows/build_linux.yml
vendored
@@ -45,7 +45,8 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev libwayland-dev
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
|
|||||||
11
.github/workflows/build_windows.yml
vendored
11
.github/workflows/build_windows.yml
vendored
@@ -4,6 +4,7 @@ on: [push, pull_request]
|
|||||||
env:
|
env:
|
||||||
DOTNET_NOLOGO: true
|
DOTNET_NOLOGO: true
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
DOTNET_ROLL_FORWARD: 'minor'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.419
|
||||||
- name: Print .NET info
|
- name: Print .NET info
|
||||||
run: |
|
run: |
|
||||||
dotnet --info
|
dotnet --info
|
||||||
@@ -30,6 +31,9 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
PowerShell "(Get-Content global.json).Replace('latestMajor', 'minor') | Set-Content global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/global.json).Replace('latestMajor', 'minor') | Set-Content Source/Tools/Flax.Build/global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/Flax.Build.csproj).Replace('LatestMajor', 'Minor') | Set-Content Source/Tools/Flax.Build/Flax.Build.csproj"
|
||||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=8 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxEditor
|
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=8 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxEditor
|
||||||
|
|
||||||
# Game
|
# Game
|
||||||
@@ -44,7 +48,7 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.419
|
||||||
- name: Print .NET info
|
- name: Print .NET info
|
||||||
run: |
|
run: |
|
||||||
dotnet --info
|
dotnet --info
|
||||||
@@ -55,4 +59,7 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
PowerShell "(Get-Content global.json).Replace('latestMajor', 'minor') | Set-Content global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/global.json).Replace('latestMajor', 'minor') | Set-Content Source/Tools/Flax.Build/global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/Flax.Build.csproj).Replace('LatestMajor', 'Minor') | Set-Content Source/Tools/Flax.Build/Flax.Build.csproj"
|
||||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=8 -arch=x64 -platform=Windows -configuration=Release -buildtargets=FlaxGame
|
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -printSDKs -dotnet=8 -arch=x64 -platform=Windows -configuration=Release -buildtargets=FlaxGame
|
||||||
|
|||||||
15
.github/workflows/cd.yml
vendored
15
.github/workflows/cd.yml
vendored
@@ -7,6 +7,7 @@ on:
|
|||||||
env:
|
env:
|
||||||
DOTNET_NOLOGO: true
|
DOTNET_NOLOGO: true
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
DOTNET_ROLL_FORWARD: 'minor'
|
||||||
GIT_LFS_PULL_OPTIONS: '-c lfs.concurrenttransfers=1 -c lfs.transfer.maxretries=2 -c http.version="HTTP/1.1" -c lfs.activitytimeout=60'
|
GIT_LFS_PULL_OPTIONS: '-c lfs.concurrenttransfers=1 -c lfs.transfer.maxretries=2 -c http.version="HTTP/1.1" -c lfs.activitytimeout=60'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -27,13 +28,16 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.419
|
||||||
- name: Print .NET info
|
- name: Print .NET info
|
||||||
run: |
|
run: |
|
||||||
dotnet --info
|
dotnet --info
|
||||||
dotnet workload --info
|
dotnet workload --info
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
PowerShell "(Get-Content global.json).Replace('latestMajor', 'minor') | Set-Content global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/global.json).Replace('latestMajor', 'minor') | Set-Content Source/Tools/Flax.Build/global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/Flax.Build.csproj).Replace('LatestMajor', 'Minor') | Set-Content Source/Tools/Flax.Build/Flax.Build.csproj"
|
||||||
.\PackageEditor.bat -arch=x64 -platform=Windows -deployOutput=Output -dotnet=8
|
.\PackageEditor.bat -arch=x64 -platform=Windows -deployOutput=Output -dotnet=8
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
@@ -60,13 +64,16 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.419
|
||||||
- name: Print .NET info
|
- name: Print .NET info
|
||||||
run: |
|
run: |
|
||||||
dotnet --info
|
dotnet --info
|
||||||
dotnet workload --info
|
dotnet workload --info
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
PowerShell "(Get-Content global.json).Replace('latestMajor', 'minor') | Set-Content global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/global.json).Replace('latestMajor', 'minor') | Set-Content Source/Tools/Flax.Build/global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/Flax.Build.csproj).Replace('LatestMajor', 'Minor') | Set-Content Source/Tools/Flax.Build/Flax.Build.csproj"
|
||||||
.\PackagePlatforms.bat -arch=x64 -platform=Windows -deployOutput=Output -dotnet=8
|
.\PackagePlatforms.bat -arch=x64 -platform=Windows -deployOutput=Output -dotnet=8
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
@@ -88,7 +95,7 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
@@ -120,7 +127,7 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
|
|||||||
19
.github/workflows/tests.yml
vendored
19
.github/workflows/tests.yml
vendored
@@ -4,6 +4,7 @@ on: [push, pull_request]
|
|||||||
env:
|
env:
|
||||||
DOTNET_NOLOGO: true
|
DOTNET_NOLOGO: true
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
|
DOTNET_ROLL_FORWARD: 'minor'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@@ -29,25 +30,22 @@ jobs:
|
|||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev gdb
|
||||||
|
chmod +x .github/data/bt.sh
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
|
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
|
||||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=8 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget
|
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=8 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
|
||||||
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||||
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
dotnet msbuild Source/Tools/Flax.Build.Tests/Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||||
- name: Test
|
- name: Test
|
||||||
run: |
|
run: |
|
||||||
${GITHUB_WORKSPACE}/Binaries/Editor/Linux/Development/FlaxTests
|
${GITHUB_WORKSPACE}/.github/data/bt.sh ./Binaries/Editor/Linux/Development/FlaxTests -headless
|
||||||
dotnet test -f net8.0 Binaries/Tests/Flax.Build.Tests.dll
|
dotnet test -f net8.0 Binaries/Tests/Flax.Build.Tests.dll
|
||||||
cp Binaries/Editor/Linux/Development/FlaxEngine.CSharp.dll Binaries/Tests
|
cp Binaries/Editor/Linux/Development/FlaxEngine.CSharp.dll Binaries/Tests
|
||||||
cp Binaries/Editor/Linux/Development/FlaxEngine.CSharp.runtimeconfig.json Binaries/Tests
|
cp Binaries/Editor/Linux/Development/FlaxEngine.CSharp.runtimeconfig.json Binaries/Tests
|
||||||
cp Binaries/Editor/Linux/Development/Newtonsoft.Json.dll Binaries/Tests
|
cp Binaries/Editor/Linux/Development/Newtonsoft.Json.dll Binaries/Tests
|
||||||
dotnet test -f net8.0 Binaries/Tests/FlaxEngine.CSharp.dll
|
dotnet test -f net8.0 Binaries/Tests/FlaxEngine.CSharp.dll
|
||||||
- name: Test UseLargeWorlds
|
|
||||||
run: |
|
|
||||||
./Development/Scripts/Linux/CallBuildTool.sh -build -log -dotnet=8 -arch=x64 -platform=Linux -configuration=Development -buildtargets=FlaxTestsTarget -UseLargeWorlds=true
|
|
||||||
${GITHUB_WORKSPACE}/Binaries/Editor/Linux/Development/FlaxTests
|
|
||||||
|
|
||||||
# Tests on Windows
|
# Tests on Windows
|
||||||
tests-windows:
|
tests-windows:
|
||||||
@@ -59,7 +57,7 @@ jobs:
|
|||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.0.x
|
dotnet-version: 8.0.419
|
||||||
- name: Print .NET info
|
- name: Print .NET info
|
||||||
run: |
|
run: |
|
||||||
dotnet --info
|
dotnet --info
|
||||||
@@ -70,6 +68,9 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
PowerShell "(Get-Content global.json).Replace('latestMajor', 'minor') | Set-Content global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/global.json).Replace('latestMajor', 'minor') | Set-Content Source/Tools/Flax.Build/global.json"
|
||||||
|
PowerShell "(Get-Content Source/Tools/Flax.Build/Flax.Build.csproj).Replace('LatestMajor', 'Minor') | Set-Content Source/Tools/Flax.Build/Flax.Build.csproj"
|
||||||
.\GenerateProjectFiles.bat -vs2022 -log -verbose -printSDKs -dotnet=8
|
.\GenerateProjectFiles.bat -vs2022 -log -verbose -printSDKs -dotnet=8
|
||||||
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -dotnet=8 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
|
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -dotnet=8 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
|
||||||
dotnet msbuild Source\Tools\Flax.Build.Tests\Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
dotnet msbuild Source\Tools\Flax.Build.Tests\Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
|
||||||
@@ -77,7 +78,7 @@ jobs:
|
|||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
.\Binaries\Editor\Win64\Development\FlaxTests.exe
|
.\Binaries\Editor\Win64\Development\FlaxTests.exe -headless
|
||||||
if(!$?) { Write-Host "Tests failed with exit code $LastExitCode" -ForegroundColor Red; Exit $LastExitCode }
|
if(!$?) { Write-Host "Tests failed with exit code $LastExitCode" -ForegroundColor Red; Exit $LastExitCode }
|
||||||
dotnet test -f net8.0 Binaries\Tests\Flax.Build.Tests.dll
|
dotnet test -f net8.0 Binaries\Tests\Flax.Build.Tests.dll
|
||||||
xcopy /y Binaries\Editor\Win64\Development\FlaxEngine.CSharp.dll Binaries\Tests
|
xcopy /y Binaries\Editor\Win64\Development\FlaxEngine.CSharp.dll Binaries\Tests
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Editor/HSWheel.flax
LFS
Normal file
BIN
Content/Editor/HSWheel.flax
LFS
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Editor/IconsAtlas.flax
LFS
BIN
Content/Editor/IconsAtlas.flax
LFS
Binary file not shown.
Binary file not shown.
@@ -42,10 +42,10 @@ struct MaterialInput
|
|||||||
float2 SvPositionToDecalUV(float4 svPosition)
|
float2 SvPositionToDecalUV(float4 svPosition)
|
||||||
{
|
{
|
||||||
float2 screenUV = svPosition.xy * ScreenSize.zw;
|
float2 screenUV = svPosition.xy * ScreenSize.zw;
|
||||||
svPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;
|
svPosition.z = SAMPLE_RT_DEPTH(DepthBuffer, screenUV);
|
||||||
float4 positionHS = mul(float4(svPosition.xyz, 1), SvPositionToWorld);
|
float4 positionHS = PROJECT_POINT(float4(svPosition.xyz, 1), SvPositionToWorld);
|
||||||
float3 positionWS = positionHS.xyz / positionHS.w;
|
float3 positionWS = positionHS.xyz / positionHS.w;
|
||||||
float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz;
|
float3 positionOS = PROJECT_POINT(float4(positionWS, 1), InvWorld).xyz;
|
||||||
return positionOS.xz + 0.5f;
|
return positionOS.xz + 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,10 +182,10 @@ META_VS_IN_ELEMENT(POSITION, 0, R32G32B32_FLOAT, 0, 0, PER_VERTEX, 0, true)
|
|||||||
void VS_Decal(in float3 Position : POSITION0, out float4 SvPosition : SV_Position)
|
void VS_Decal(in float3 Position : POSITION0, out float4 SvPosition : SV_Position)
|
||||||
{
|
{
|
||||||
// Compute world space vertex position
|
// Compute world space vertex position
|
||||||
float3 worldPosition = mul(float4(Position.xyz, 1), WorldMatrix).xyz;
|
float3 worldPosition = PROJECT_POINT(float4(Position.xyz, 1), WorldMatrix).xyz;
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
SvPosition = mul(float4(worldPosition.xyz, 1), ViewProjectionMatrix);
|
SvPosition = PROJECT_POINT(float4(worldPosition.xyz, 1), ViewProjectionMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pixel Shader function for decals rendering
|
// Pixel Shader function for decals rendering
|
||||||
@@ -213,11 +213,11 @@ void PS_Decal(
|
|||||||
}
|
}
|
||||||
|
|
||||||
float2 screenUV = SvPosition.xy * ScreenSize.zw;
|
float2 screenUV = SvPosition.xy * ScreenSize.zw;
|
||||||
SvPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;
|
SvPosition.z = SAMPLE_RT_DEPTH(DepthBuffer, screenUV);
|
||||||
|
|
||||||
float4 positionHS = mul(float4(SvPosition.xyz, 1), SvPositionToWorld);
|
float4 positionHS = PROJECT_POINT(float4(SvPosition.xyz, 1), SvPositionToWorld);
|
||||||
float3 positionWS = positionHS.xyz / positionHS.w;
|
float3 positionWS = positionHS.xyz / positionHS.w;
|
||||||
float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz;
|
float3 positionOS = PROJECT_POINT(float4(positionWS, 1), InvWorld).xyz;
|
||||||
|
|
||||||
clip(0.5 - abs(positionOS.xyz));
|
clip(0.5 - abs(positionOS.xyz));
|
||||||
float2 decalUVs = positionOS.xz + 0.5f;
|
float2 decalUVs = positionOS.xz + 0.5f;
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ VertexOutput VS_SplineModel(ModelInput input)
|
|||||||
world = mul(world, WorldMatrix);
|
world = mul(world, WorldMatrix);
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
|
|
||||||
// Pass vertex attributes
|
// Pass vertex attributes
|
||||||
output.Geometry.TexCoord = input.TexCoord0;
|
output.Geometry.TexCoord = input.TexCoord0;
|
||||||
@@ -337,8 +337,7 @@ VertexOutput VS_SplineModel(ModelInput input)
|
|||||||
// Apply world position offset per-vertex
|
// Apply world position offset per-vertex
|
||||||
#if USE_POSITION_OFFSET
|
#if USE_POSITION_OFFSET
|
||||||
output.Geometry.WorldPosition += material.PositionOffset;
|
output.Geometry.WorldPosition += material.PositionOffset;
|
||||||
output.Geometry.PrevWorldPosition += material.PositionOffset;
|
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get tessalation multiplier (per vertex)
|
// Get tessalation multiplier (per vertex)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ float Rand(inout uint seed)
|
|||||||
float3 ReprojectPosition(float2 uv, float rawDepth)
|
float3 ReprojectPosition(float2 uv, float rawDepth)
|
||||||
{
|
{
|
||||||
uv = uv * float2(2.0, -2.0) + float2(-1.0, 1.0);
|
uv = uv * float2(2.0, -2.0) + float2(-1.0, 1.0);
|
||||||
float4 pos = mul(float4(uv.x, uv.y, rawDepth, 1.0f), InvViewProjectionMatrix);
|
float4 pos = PROJECT_POINT(float4(uv.x, uv.y, rawDepth, 1.0f), InvViewProjectionMatrix);
|
||||||
return pos.xyz / pos.w;
|
return pos.xyz / pos.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ void SpawnParticle(Context context)
|
|||||||
@4}
|
@4}
|
||||||
|
|
||||||
// Main entry point for the particles simulation and spawning
|
// Main entry point for the particles simulation and spawning
|
||||||
META_CS(true, FEATURE_LEVEL_SM5)
|
META_CS(true, AUTO)
|
||||||
[numthreads(THREAD_GROUP_SIZE, 1, 1)]
|
[numthreads(THREAD_GROUP_SIZE, 1, 1)]
|
||||||
void CS_Main(uint3 dispatchThreadId : SV_DispatchThreadID)
|
void CS_Main(uint3 dispatchThreadId : SV_DispatchThreadID)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ VertexOutput VS_GUI(Render2DVertex input)
|
|||||||
if ((int)input.CustomDataAndClipOrigin.y & 1)
|
if ((int)input.CustomDataAndClipOrigin.y & 1)
|
||||||
input.Position = (int2)input.Position;
|
input.Position = (int2)input.Position;
|
||||||
|
|
||||||
output.Position = mul(float4(input.Position, 0, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(input.Position, 0, 1), ViewProjectionMatrix);
|
||||||
output.WorldPosition = mul(float4(input.Position, 0, 1), WorldMatrix).xyz;
|
output.WorldPosition = mul(float4(input.Position, 0, 1), WorldMatrix).xyz;
|
||||||
output.TexCoord = input.TexCoord;
|
output.TexCoord = input.TexCoord;
|
||||||
output.WindowPos = input.Position;
|
output.WindowPos = input.Position;
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
|||||||
output.WorldPosition = position + spriteVertexPosition;
|
output.WorldPosition = position + spriteVertexPosition;
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
||||||
|
|
||||||
// Pass vertex attributes
|
// Pass vertex attributes
|
||||||
output.TexCoord = input.TexCoord;
|
output.TexCoord = input.TexCoord;
|
||||||
@@ -431,7 +431,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
|||||||
// Apply world position offset per-vertex
|
// Apply world position offset per-vertex
|
||||||
#if USE_POSITION_OFFSET
|
#if USE_POSITION_OFFSET
|
||||||
output.WorldPosition += material.PositionOffset;
|
output.WorldPosition += material.PositionOffset;
|
||||||
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Copy interpolants for other shader stages
|
// Copy interpolants for other shader stages
|
||||||
@@ -511,7 +511,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
|||||||
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
|
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
|
|
||||||
// Pass vertex attributes
|
// Pass vertex attributes
|
||||||
output.TexCoord = input.TexCoord0;
|
output.TexCoord = input.TexCoord0;
|
||||||
@@ -549,7 +549,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
|||||||
// Apply world position offset per-vertex
|
// Apply world position offset per-vertex
|
||||||
#if USE_POSITION_OFFSET
|
#if USE_POSITION_OFFSET
|
||||||
output.WorldPosition += material.PositionOffset;
|
output.WorldPosition += material.PositionOffset;
|
||||||
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Copy interpolants for other shader stages
|
// Copy interpolants for other shader stages
|
||||||
@@ -617,7 +617,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
|
|||||||
output.WorldPosition = position + tangentRight * vertexSign * (ribbonWidth.xxx * 0.5f);
|
output.WorldPosition = position + tangentRight * vertexSign * (ribbonWidth.xxx * 0.5f);
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
||||||
|
|
||||||
// Pass vertex attributes
|
// Pass vertex attributes
|
||||||
output.ParticleIndex = particleIndex;
|
output.ParticleIndex = particleIndex;
|
||||||
@@ -655,7 +655,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
|
|||||||
// Apply world position offset per-vertex
|
// Apply world position offset per-vertex
|
||||||
#if USE_POSITION_OFFSET
|
#if USE_POSITION_OFFSET
|
||||||
output.WorldPosition += material.PositionOffset;
|
output.WorldPosition += material.PositionOffset;
|
||||||
output.Position = mul(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.WorldPosition.xyz, 1), ViewProjectionMatrix);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Copy interpolants for other shader stages
|
// Copy interpolants for other shader stages
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ VertexOutput VS(ModelInput input)
|
|||||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), object.PrevWorldMatrix).xyz;
|
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), object.PrevWorldMatrix).xyz;
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
|
|
||||||
// Pass vertex attributes
|
// Pass vertex attributes
|
||||||
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
|
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
|
||||||
@@ -378,7 +378,7 @@ VertexOutput VS(ModelInput input)
|
|||||||
#if USE_POSITION_OFFSET
|
#if USE_POSITION_OFFSET
|
||||||
output.Geometry.WorldPosition += material.PositionOffset;
|
output.Geometry.WorldPosition += material.PositionOffset;
|
||||||
output.Geometry.PrevWorldPosition += material.PositionOffset;
|
output.Geometry.PrevWorldPosition += material.PositionOffset;
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get tessalation multiplier (per vertex)
|
// Get tessalation multiplier (per vertex)
|
||||||
@@ -412,7 +412,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
|
|||||||
|
|
||||||
// Transform vertex position into the screen
|
// Transform vertex position into the screen
|
||||||
float3 worldPosition = mul(float4(input.Position.xyz, 1), object.WorldMatrix).xyz;
|
float3 worldPosition = mul(float4(input.Position.xyz, 1), object.WorldMatrix).xyz;
|
||||||
float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix);
|
float4 position = PROJECT_POINT(float4(worldPosition, 1), ViewProjectionMatrix);
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,7 +518,7 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
|
|
||||||
// Pass vertex attributes
|
// Pass vertex attributes
|
||||||
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
|
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
|
||||||
@@ -549,7 +549,7 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
|
|||||||
#if USE_POSITION_OFFSET
|
#if USE_POSITION_OFFSET
|
||||||
output.Geometry.WorldPosition += material.PositionOffset;
|
output.Geometry.WorldPosition += material.PositionOffset;
|
||||||
output.Geometry.PrevWorldPosition += material.PositionOffset;
|
output.Geometry.PrevWorldPosition += material.PositionOffset;
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get tessalation multiplier (per vertex)
|
// Get tessalation multiplier (per vertex)
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ VertexOutput VS(TerrainVertexInput input)
|
|||||||
output.Geometry.WorldPosition = mul(float4(position, 1), worldMatrix).xyz;
|
output.Geometry.WorldPosition = mul(float4(position, 1), worldMatrix).xyz;
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
|
|
||||||
// Pass vertex attributes
|
// Pass vertex attributes
|
||||||
#if USE_SMOOTH_LOD_TRANSITION
|
#if USE_SMOOTH_LOD_TRANSITION
|
||||||
@@ -436,7 +436,7 @@ VertexOutput VS(TerrainVertexInput input)
|
|||||||
// Apply world position offset per-vertex
|
// Apply world position offset per-vertex
|
||||||
#if USE_POSITION_OFFSET
|
#if USE_POSITION_OFFSET
|
||||||
output.Geometry.WorldPosition += material.PositionOffset;
|
output.Geometry.WorldPosition += material.PositionOffset;
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = PROJECT_POINT(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get tessalation multiplier (per vertex)
|
// Get tessalation multiplier (per vertex)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/BitonicSort.flax
LFS
BIN
Content/Shaders/BitonicSort.flax
LFS
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/DebugDraw.flax
LFS
BIN
Content/Shaders/DebugDraw.flax
LFS
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Fog.flax
LFS
BIN
Content/Shaders/Fog.flax
LFS
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/GUI.flax
LFS
BIN
Content/Shaders/GUI.flax
LFS
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Histogram.flax
LFS
BIN
Content/Shaders/Histogram.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Lights.flax
LFS
BIN
Content/Shaders/Lights.flax
LFS
Binary file not shown.
BIN
Content/Shaders/MotionBlur.flax
LFS
BIN
Content/Shaders/MotionBlur.flax
LFS
Binary file not shown.
BIN
Content/Shaders/MultiScaler.flax
LFS
BIN
Content/Shaders/MultiScaler.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Quad.flax
LFS
BIN
Content/Shaders/Quad.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Reflections.flax
LFS
BIN
Content/Shaders/Reflections.flax
LFS
Binary file not shown.
BIN
Content/Shaders/SSAO.flax
LFS
BIN
Content/Shaders/SSAO.flax
LFS
Binary file not shown.
BIN
Content/Shaders/SSR.flax
LFS
BIN
Content/Shaders/SSR.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Shadows.flax
LFS
BIN
Content/Shaders/Shadows.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Sky.flax
LFS
BIN
Content/Shaders/Sky.flax
LFS
Binary file not shown.
BIN
Content/Shaders/TAA.flax
LFS
BIN
Content/Shaders/TAA.flax
LFS
Binary file not shown.
@@ -4,7 +4,7 @@
|
|||||||
"Major": 1,
|
"Major": 1,
|
||||||
"Minor": 12,
|
"Minor": 12,
|
||||||
"Revision": 0,
|
"Revision": 0,
|
||||||
"Build": 6905
|
"Build": 6910
|
||||||
},
|
},
|
||||||
"Company": "Flax",
|
"Company": "Flax",
|
||||||
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",
|
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",
|
||||||
@@ -14,6 +14,14 @@
|
|||||||
"UseCSharp": true,
|
"UseCSharp": true,
|
||||||
"UseLargeWorlds": false,
|
"UseLargeWorlds": false,
|
||||||
"UseDotNet": true,
|
"UseDotNet": true,
|
||||||
"UseSDL": true
|
"Windows": {
|
||||||
|
"UseSDL": false,
|
||||||
|
},
|
||||||
|
"Mac": {
|
||||||
|
"UseSDL": false,
|
||||||
|
},
|
||||||
|
"Linux": {
|
||||||
|
"UseSDL": true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ cd "`dirname "$0"`"
|
|||||||
bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
||||||
|
|
||||||
# Build bindings for all editor configurations
|
# Build bindings for all editor configurations
|
||||||
#echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
# TODO: Detect the correct architecture here
|
# TODO: Detect the correct architecture here
|
||||||
#Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace FlaxEditor.Content.GUI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the target node.
|
/// Gets the target node.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ContentTreeNode TargetNode { get; }
|
public ContentFolderTreeNode TargetNode { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ContentNavigationButton"/> class.
|
/// Initializes a new instance of the <see cref="ContentNavigationButton"/> class.
|
||||||
@@ -28,7 +28,7 @@ namespace FlaxEditor.Content.GUI
|
|||||||
/// <param name="x">The x position.</param>
|
/// <param name="x">The x position.</param>
|
||||||
/// <param name="y">The y position.</param>
|
/// <param name="y">The y position.</param>
|
||||||
/// <param name="height">The height.</param>
|
/// <param name="height">The height.</param>
|
||||||
public ContentNavigationButton(ContentTreeNode targetNode, float x, float y, float height)
|
public ContentNavigationButton(ContentFolderTreeNode targetNode, float x, float y, float height)
|
||||||
: base(x, y, height)
|
: base(x, y, height)
|
||||||
{
|
{
|
||||||
TargetNode = targetNode;
|
TargetNode = targetNode;
|
||||||
@@ -147,7 +147,7 @@ namespace FlaxEditor.Content.GUI
|
|||||||
ClearItems();
|
ClearItems();
|
||||||
foreach (var child in Target.TargetNode.Children)
|
foreach (var child in Target.TargetNode.Children)
|
||||||
{
|
{
|
||||||
if (child is ContentTreeNode node)
|
if (child is ContentFolderTreeNode node)
|
||||||
{
|
{
|
||||||
if (node.Folder.VisibleInHierarchy) // Respect the filter set by ContentFilterConfig.Filter(...)
|
if (node.Folder.VisibleInHierarchy) // Respect the filter set by ContentFilterConfig.Filter(...)
|
||||||
AddItem(node.Folder.ShortName);
|
AddItem(node.Folder.ShortName);
|
||||||
@@ -180,7 +180,7 @@ namespace FlaxEditor.Content.GUI
|
|||||||
var item = _items[index];
|
var item = _items[index];
|
||||||
foreach (var child in Target.TargetNode.Children)
|
foreach (var child in Target.TargetNode.Children)
|
||||||
{
|
{
|
||||||
if (child is ContentTreeNode node && node.Folder.ShortName == item)
|
if (child is ContentFolderTreeNode node && node.Folder.ShortName == item)
|
||||||
{
|
{
|
||||||
Editor.Instance.Windows.ContentWin.Navigate(node);
|
Editor.Instance.Windows.ContentWin.Navigate(node);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace FlaxEditor.Content
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the content node.
|
/// Gets the content node.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ContentTreeNode Node { get; }
|
public ContentFolderTreeNode Node { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The subitems of this folder.
|
/// The subitems of this folder.
|
||||||
@@ -72,7 +72,7 @@ namespace FlaxEditor.Content
|
|||||||
/// <param name="type">The folder type.</param>
|
/// <param name="type">The folder type.</param>
|
||||||
/// <param name="path">The path to the item.</param>
|
/// <param name="path">The path to the item.</param>
|
||||||
/// <param name="node">The folder parent node.</param>
|
/// <param name="node">The folder parent node.</param>
|
||||||
internal ContentFolder(ContentFolderType type, string path, ContentTreeNode node)
|
internal ContentFolder(ContentFolderType type, string path, ContentFolderTreeNode node)
|
||||||
: base(path)
|
: base(path)
|
||||||
{
|
{
|
||||||
FolderType = type;
|
FolderType = type;
|
||||||
@@ -118,7 +118,7 @@ namespace FlaxEditor.Content
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
var hasParentFolder = ParentFolder != null;
|
var hasParentFolder = ParentFolder != null;
|
||||||
var isContentFolder = Node is MainContentTreeNode;
|
var isContentFolder = Node is MainContentFolderTreeNode;
|
||||||
return hasParentFolder && !isContentFolder;
|
return hasParentFolder && !isContentFolder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ namespace FlaxEditor.Content.Thumbnails
|
|||||||
{
|
{
|
||||||
if (item == null)
|
if (item == null)
|
||||||
throw new ArgumentNullException();
|
throw new ArgumentNullException();
|
||||||
|
if (_task == null)
|
||||||
|
return;
|
||||||
|
|
||||||
// Check if use default icon
|
// Check if use default icon
|
||||||
var defaultThumbnail = item.DefaultThumbnail;
|
var defaultThumbnail = item.DefaultThumbnail;
|
||||||
@@ -223,11 +225,12 @@ namespace FlaxEditor.Content.Thumbnails
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnInit()
|
public override void OnInit()
|
||||||
{
|
{
|
||||||
|
if (Editor.IsHeadlessMode || (GPUDevice.Instance != null && GPUDevice.Instance.RendererType == RendererType.Null))
|
||||||
|
return;
|
||||||
|
|
||||||
// Create cache folder
|
// Create cache folder
|
||||||
if (!Directory.Exists(_cacheFolder))
|
if (!Directory.Exists(_cacheFolder))
|
||||||
{
|
|
||||||
Directory.CreateDirectory(_cacheFolder);
|
Directory.CreateDirectory(_cacheFolder);
|
||||||
}
|
|
||||||
|
|
||||||
// Find atlases in a Editor cache directory
|
// Find atlases in a Editor cache directory
|
||||||
var files = Directory.GetFiles(_cacheFolder, "cache_*.flax", SearchOption.TopDirectoryOnly);
|
var files = Directory.GetFiles(_cacheFolder, "cache_*.flax", SearchOption.TopDirectoryOnly);
|
||||||
@@ -482,7 +485,7 @@ namespace FlaxEditor.Content.Thumbnails
|
|||||||
public override void OnUpdate()
|
public override void OnUpdate()
|
||||||
{
|
{
|
||||||
// Wait some frames before start generating previews (late init feature)
|
// Wait some frames before start generating previews (late init feature)
|
||||||
if (Time.TimeSinceStartup < 1.0f || HasAllAtlasesLoaded() == false)
|
if (Time.TimeSinceStartup < 1.0f || HasAllAtlasesLoaded() == false || _task == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock (_requests)
|
lock (_requests)
|
||||||
|
|||||||
433
Source/Editor/Content/Tree/ContentFolderTreeNode.cs
Normal file
433
Source/Editor/Content/Tree/ContentFolderTreeNode.cs
Normal file
@@ -0,0 +1,433 @@
|
|||||||
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FlaxEditor.GUI;
|
||||||
|
using FlaxEditor.GUI.Drag;
|
||||||
|
using FlaxEditor.GUI.Tree;
|
||||||
|
using FlaxEditor.SceneGraph;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
|
namespace FlaxEditor.Content;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Content folder tree node.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="TreeNode" />
|
||||||
|
public class ContentFolderTreeNode : TreeNode
|
||||||
|
{
|
||||||
|
private DragItems _dragOverItems;
|
||||||
|
private DragActors _dragActors;
|
||||||
|
private List<Rectangle> _highlights;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The folder.
|
||||||
|
/// </summary>
|
||||||
|
protected ContentFolder _folder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this node can be deleted.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool CanDelete => true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether this node can be duplicated.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool CanDuplicate => true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the content folder item.
|
||||||
|
/// </summary>
|
||||||
|
public ContentFolder Folder => _folder;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of the folder.
|
||||||
|
/// </summary>
|
||||||
|
public ContentFolderType FolderType => _folder.FolderType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if that folder can import/manage scripts.
|
||||||
|
/// </summary>
|
||||||
|
public bool CanHaveScripts => _folder.CanHaveScripts;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if that folder can import/manage assets.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if can contain assets for project, otherwise false</returns>
|
||||||
|
public bool CanHaveAssets => _folder.CanHaveAssets;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the parent node.
|
||||||
|
/// </summary>
|
||||||
|
public ContentFolderTreeNode ParentNode => Parent as ContentFolderTreeNode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the folder path.
|
||||||
|
/// </summary>
|
||||||
|
public string Path => _folder.Path;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the navigation button label.
|
||||||
|
/// </summary>
|
||||||
|
public virtual string NavButtonLabel => _folder.ShortName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ContentFolderTreeNode"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">The parent node.</param>
|
||||||
|
/// <param name="path">The folder path.</param>
|
||||||
|
public ContentFolderTreeNode(ContentFolderTreeNode parent, string path)
|
||||||
|
: this(parent, parent?.FolderType ?? ContentFolderType.Other, path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ContentFolderTreeNode"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parent">The parent node.</param>
|
||||||
|
/// <param name="type">The folder type.</param>
|
||||||
|
/// <param name="path">The folder path.</param>
|
||||||
|
protected ContentFolderTreeNode(ContentFolderTreeNode parent, ContentFolderType type, string path)
|
||||||
|
: base(false, Editor.Instance.Icons.FolderClosed32, Editor.Instance.Icons.FolderOpen32)
|
||||||
|
{
|
||||||
|
_folder = new ContentFolder(type, path, this);
|
||||||
|
Text = _folder.ShortName;
|
||||||
|
if (parent != null)
|
||||||
|
{
|
||||||
|
Folder.ParentFolder = parent.Folder;
|
||||||
|
Parent = parent;
|
||||||
|
}
|
||||||
|
IconColor = Color.Transparent; // Hide default icon, we draw scaled icon manually
|
||||||
|
UpdateCustomArrowRect();
|
||||||
|
Editor.Instance?.Windows?.ContentWin?.TryAutoExpandContentNode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the custom arrow rectangle so it stays aligned with the current layout.
|
||||||
|
/// </summary>
|
||||||
|
private void UpdateCustomArrowRect()
|
||||||
|
{
|
||||||
|
var contentWindow = Editor.Instance?.Windows?.ContentWin;
|
||||||
|
var scale = contentWindow != null && contentWindow.IsTreeOnlyMode ? contentWindow.View.ViewScale : 1.0f;
|
||||||
|
var arrowSize = Mathf.Clamp(12.0f * scale, 10.0f, 20.0f);
|
||||||
|
var iconSize = Mathf.Clamp(16.0f * scale, 12.0f, 28.0f);
|
||||||
|
|
||||||
|
// Use the current text layout, not just cached values.
|
||||||
|
var textRect = TextRect;
|
||||||
|
var iconLeft = textRect.Left - iconSize - 2.0f;
|
||||||
|
var x = Mathf.Max(iconLeft - arrowSize - 2.0f, 0.0f);
|
||||||
|
var y = Mathf.Max((HeaderHeight - arrowSize) * 0.5f, 0.0f);
|
||||||
|
|
||||||
|
CustomArrowRect = new Rectangle(x, y, arrowSize, arrowSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PerformLayout(bool force = false)
|
||||||
|
{
|
||||||
|
base.PerformLayout(force);
|
||||||
|
UpdateCustomArrowRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows the rename popup for the item.
|
||||||
|
/// </summary>
|
||||||
|
public void StartRenaming()
|
||||||
|
{
|
||||||
|
if (!_folder.CanRename)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Start renaming the folder
|
||||||
|
Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(false);
|
||||||
|
var dialog = RenamePopup.Show(this, TextRect, _folder.ShortName, false);
|
||||||
|
dialog.Tag = _folder;
|
||||||
|
dialog.Renamed += popup =>
|
||||||
|
{
|
||||||
|
Editor.Instance.Windows.ContentWin.Rename((ContentFolder)popup.Tag, popup.Text);
|
||||||
|
Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(true);
|
||||||
|
};
|
||||||
|
dialog.Closed += popup => { Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(true); };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the query search filter.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filterText">The filter text.</param>
|
||||||
|
public void UpdateFilter(string filterText)
|
||||||
|
{
|
||||||
|
bool noFilter = string.IsNullOrWhiteSpace(filterText);
|
||||||
|
|
||||||
|
// Update itself
|
||||||
|
bool isThisVisible;
|
||||||
|
if (noFilter)
|
||||||
|
{
|
||||||
|
// Clear filter
|
||||||
|
_highlights?.Clear();
|
||||||
|
isThisVisible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var text = Text;
|
||||||
|
if (QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges))
|
||||||
|
{
|
||||||
|
// Update highlights
|
||||||
|
if (_highlights == null)
|
||||||
|
_highlights = new List<Rectangle>(ranges.Length);
|
||||||
|
else
|
||||||
|
_highlights.Clear();
|
||||||
|
var style = Style.Current;
|
||||||
|
var font = style.FontSmall;
|
||||||
|
var textRect = TextRect;
|
||||||
|
for (int i = 0; i < ranges.Length; i++)
|
||||||
|
{
|
||||||
|
var start = font.GetCharPosition(text, ranges[i].StartIndex);
|
||||||
|
var end = font.GetCharPosition(text, ranges[i].EndIndex);
|
||||||
|
_highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height));
|
||||||
|
}
|
||||||
|
isThisVisible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hide
|
||||||
|
_highlights?.Clear();
|
||||||
|
isThisVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update children
|
||||||
|
bool isAnyChildVisible = false;
|
||||||
|
for (int i = 0; i < _children.Count; i++)
|
||||||
|
{
|
||||||
|
if (_children[i] is ContentFolderTreeNode child)
|
||||||
|
{
|
||||||
|
child.UpdateFilter(filterText);
|
||||||
|
isAnyChildVisible |= child.Visible;
|
||||||
|
}
|
||||||
|
else if (_children[i] is ContentItemTreeNode itemNode)
|
||||||
|
{
|
||||||
|
itemNode.UpdateFilter(filterText);
|
||||||
|
isAnyChildVisible |= itemNode.Visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!noFilter)
|
||||||
|
{
|
||||||
|
bool isExpanded = isAnyChildVisible;
|
||||||
|
if (isExpanded)
|
||||||
|
Expand(true);
|
||||||
|
else
|
||||||
|
Collapse(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Visible = isThisVisible | isAnyChildVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override int Compare(Control other)
|
||||||
|
{
|
||||||
|
if (other is ContentItemTreeNode)
|
||||||
|
return -1;
|
||||||
|
if (other is ContentFolderTreeNode otherNode)
|
||||||
|
return string.Compare(Text, otherNode.Text, StringComparison.Ordinal);
|
||||||
|
return base.Compare(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
base.Draw();
|
||||||
|
|
||||||
|
// Draw all highlights
|
||||||
|
if (_highlights != null)
|
||||||
|
{
|
||||||
|
var style = Style.Current;
|
||||||
|
var color = style.ProgressNormal * 0.6f;
|
||||||
|
for (int i = 0; i < _highlights.Count; i++)
|
||||||
|
Render2D.FillRectangle(_highlights[i], color);
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentWindow = Editor.Instance.Windows.ContentWin;
|
||||||
|
var scale = contentWindow != null && contentWindow.IsTreeOnlyMode ? contentWindow.View.ViewScale : 1.0f;
|
||||||
|
var icon = IsExpanded ? Editor.Instance.Icons.FolderOpen32 : Editor.Instance.Icons.FolderClosed32;
|
||||||
|
var iconSize = Mathf.Clamp(16.0f * scale, 12.0f, 28.0f);
|
||||||
|
var iconRect = new Rectangle(TextRect.Left - iconSize - 2.0f, (HeaderHeight - iconSize) * 0.5f, iconSize, iconSize);
|
||||||
|
Render2D.DrawSprite(icon, iconRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnDestroy()
|
||||||
|
{
|
||||||
|
// Delete folder item
|
||||||
|
_folder.Dispose();
|
||||||
|
|
||||||
|
base.OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnExpandedChanged()
|
||||||
|
{
|
||||||
|
base.OnExpandedChanged();
|
||||||
|
|
||||||
|
Editor.Instance?.Windows?.ContentWin?.OnContentTreeNodeExpandedChanged(this, IsExpanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DragDropEffect GetDragEffect(DragData data)
|
||||||
|
{
|
||||||
|
if (_dragActors != null && _dragActors.HasValidDrag)
|
||||||
|
return DragDropEffect.Move;
|
||||||
|
if (data is DragDataFiles)
|
||||||
|
{
|
||||||
|
if (_folder.CanHaveAssets)
|
||||||
|
return DragDropEffect.Copy;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_dragOverItems != null && _dragOverItems.HasValidDrag)
|
||||||
|
return DragDropEffect.Move;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DragDropEffect.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidateDragItem(ContentItem item)
|
||||||
|
{
|
||||||
|
// Reject itself and any parent
|
||||||
|
return item != _folder && !item.Find(_folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidateDragActors(ActorNode actor)
|
||||||
|
{
|
||||||
|
return actor.CanCreatePrefab && _folder.CanHaveAssets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ImportActors(DragActors actors)
|
||||||
|
{
|
||||||
|
Select();
|
||||||
|
foreach (var actorNode in actors.Objects)
|
||||||
|
{
|
||||||
|
var actor = actorNode.Actor;
|
||||||
|
if (actors.Objects.Contains(actorNode.ParentNode as ActorNode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Editor.Instance.Prefabs.CreatePrefab(actor, false);
|
||||||
|
}
|
||||||
|
Editor.Instance.Windows.ContentWin.RefreshView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override DragDropEffect OnDragEnterHeader(DragData data)
|
||||||
|
{
|
||||||
|
if (data is DragDataFiles)
|
||||||
|
return _folder.CanHaveAssets ? DragDropEffect.Copy : DragDropEffect.None;
|
||||||
|
|
||||||
|
if (_dragActors == null)
|
||||||
|
_dragActors = new DragActors(ValidateDragActors);
|
||||||
|
if (_dragActors.OnDragEnter(data))
|
||||||
|
return DragDropEffect.Move;
|
||||||
|
|
||||||
|
if (_dragOverItems == null)
|
||||||
|
_dragOverItems = new DragItems(ValidateDragItem);
|
||||||
|
|
||||||
|
_dragOverItems.OnDragEnter(data);
|
||||||
|
return GetDragEffect(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override DragDropEffect OnDragMoveHeader(DragData data)
|
||||||
|
{
|
||||||
|
if (data is DragDataFiles)
|
||||||
|
return _folder.CanHaveAssets ? DragDropEffect.Copy : DragDropEffect.None;
|
||||||
|
if (_dragActors != null && _dragActors.HasValidDrag)
|
||||||
|
return DragDropEffect.Move;
|
||||||
|
return GetDragEffect(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnDragLeaveHeader()
|
||||||
|
{
|
||||||
|
_dragOverItems?.OnDragLeave();
|
||||||
|
_dragActors?.OnDragLeave();
|
||||||
|
base.OnDragLeaveHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override DragDropEffect OnDragDropHeader(DragData data)
|
||||||
|
{
|
||||||
|
var result = DragDropEffect.None;
|
||||||
|
|
||||||
|
// Check if drop element or files
|
||||||
|
if (data is DragDataFiles files)
|
||||||
|
{
|
||||||
|
// Import files
|
||||||
|
Editor.Instance.ContentImporting.Import(files.Files, _folder);
|
||||||
|
result = DragDropEffect.Copy;
|
||||||
|
|
||||||
|
Expand();
|
||||||
|
}
|
||||||
|
else if (_dragActors != null && _dragActors.HasValidDrag)
|
||||||
|
{
|
||||||
|
ImportActors(_dragActors);
|
||||||
|
_dragActors.OnDragDrop();
|
||||||
|
result = DragDropEffect.Move;
|
||||||
|
|
||||||
|
Expand();
|
||||||
|
}
|
||||||
|
else if (_dragOverItems != null && _dragOverItems.HasValidDrag)
|
||||||
|
{
|
||||||
|
// Move items
|
||||||
|
Editor.Instance.ContentDatabase.Move(_dragOverItems.Objects, _folder);
|
||||||
|
result = DragDropEffect.Move;
|
||||||
|
|
||||||
|
Expand();
|
||||||
|
}
|
||||||
|
|
||||||
|
_dragOverItems?.OnDragDrop();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void DoDragDrop()
|
||||||
|
{
|
||||||
|
DoDragDrop(DragItems.GetDragData(_folder));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void OnLongPress()
|
||||||
|
{
|
||||||
|
Select();
|
||||||
|
|
||||||
|
StartRenaming();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnKeyDown(KeyboardKeys key)
|
||||||
|
{
|
||||||
|
if (IsFocused)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case KeyboardKeys.F2:
|
||||||
|
StartRenaming();
|
||||||
|
return true;
|
||||||
|
case KeyboardKeys.Delete:
|
||||||
|
if (Folder.Exists && CanDelete)
|
||||||
|
Editor.Instance.Windows.ContentWin.Delete(Folder);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (RootWindow.GetKey(KeyboardKeys.Control))
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case KeyboardKeys.D:
|
||||||
|
if (Folder.Exists && CanDuplicate)
|
||||||
|
Editor.Instance.Windows.ContentWin.Duplicate(Folder);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnKeyDown(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
224
Source/Editor/Content/Tree/ContentItemTreeNode.cs
Normal file
224
Source/Editor/Content/Tree/ContentItemTreeNode.cs
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using FlaxEditor.Content.GUI;
|
||||||
|
using FlaxEditor.GUI.Drag;
|
||||||
|
using FlaxEditor.GUI.Tree;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
|
namespace FlaxEditor.Content;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tree node for non-folder content items.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ContentItemTreeNode : TreeNode, IContentItemOwner
|
||||||
|
{
|
||||||
|
private List<Rectangle> _highlights;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The content item.
|
||||||
|
/// </summary>
|
||||||
|
public ContentItem Item { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ContentItemTreeNode"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="item">The content item.</param>
|
||||||
|
public ContentItemTreeNode(ContentItem item)
|
||||||
|
: base(false, Editor.Instance.Icons.Document128, Editor.Instance.Icons.Document128)
|
||||||
|
{
|
||||||
|
Item = item ?? throw new ArgumentNullException(nameof(item));
|
||||||
|
UpdateDisplayedName();
|
||||||
|
IconColor = Color.Transparent; // Reserve icon space but draw custom thumbnail.
|
||||||
|
Item.AddReference(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SpriteHandle GetIcon(ContentItem item)
|
||||||
|
{
|
||||||
|
if (item == null)
|
||||||
|
return SpriteHandle.Invalid;
|
||||||
|
var icon = item.Thumbnail;
|
||||||
|
if (!icon.IsValid)
|
||||||
|
icon = item.DefaultThumbnail;
|
||||||
|
if (!icon.IsValid)
|
||||||
|
icon = Editor.Instance.Icons.Document128;
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the query search filter.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filterText">The filter text.</param>
|
||||||
|
public void UpdateFilter(string filterText)
|
||||||
|
{
|
||||||
|
bool noFilter = string.IsNullOrWhiteSpace(filterText);
|
||||||
|
bool isVisible;
|
||||||
|
if (noFilter)
|
||||||
|
{
|
||||||
|
_highlights?.Clear();
|
||||||
|
isVisible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var text = Text;
|
||||||
|
if (QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges))
|
||||||
|
{
|
||||||
|
if (_highlights == null)
|
||||||
|
_highlights = new List<Rectangle>(ranges.Length);
|
||||||
|
else
|
||||||
|
_highlights.Clear();
|
||||||
|
var style = Style.Current;
|
||||||
|
var font = style.FontSmall;
|
||||||
|
var textRect = TextRect;
|
||||||
|
for (int i = 0; i < ranges.Length; i++)
|
||||||
|
{
|
||||||
|
var start = font.GetCharPosition(text, ranges[i].StartIndex);
|
||||||
|
var end = font.GetCharPosition(text, ranges[i].EndIndex);
|
||||||
|
_highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height));
|
||||||
|
}
|
||||||
|
isVisible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_highlights?.Clear();
|
||||||
|
isVisible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Visible = isVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Draw()
|
||||||
|
{
|
||||||
|
base.Draw();
|
||||||
|
|
||||||
|
var icon = GetIcon(Item);
|
||||||
|
if (icon.IsValid)
|
||||||
|
{
|
||||||
|
var contentWindow = Editor.Instance.Windows.ContentWin;
|
||||||
|
var scale = contentWindow != null && contentWindow.IsTreeOnlyMode ? contentWindow.View.ViewScale : 1.0f;
|
||||||
|
var iconSize = Mathf.Clamp(16.0f * scale, 12.0f, 28.0f);
|
||||||
|
var textRect = TextRect;
|
||||||
|
var iconRect = new Rectangle(textRect.Left - iconSize - 2.0f, (HeaderHeight - iconSize) * 0.5f, iconSize, iconSize);
|
||||||
|
Render2D.DrawSprite(icon, iconRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_highlights != null)
|
||||||
|
{
|
||||||
|
var style = Style.Current;
|
||||||
|
var color = style.ProgressNormal * 0.6f;
|
||||||
|
for (int i = 0; i < _highlights.Count; i++)
|
||||||
|
Render2D.FillRectangle(_highlights[i], color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override bool OnMouseDoubleClickHeader(ref Float2 location, MouseButton button)
|
||||||
|
{
|
||||||
|
if (button == MouseButton.Left)
|
||||||
|
{
|
||||||
|
Editor.Instance.Windows.ContentWin.Open(Item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnMouseDoubleClickHeader(ref location, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnKeyDown(KeyboardKeys key)
|
||||||
|
{
|
||||||
|
if (IsFocused)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case KeyboardKeys.Return:
|
||||||
|
Editor.Instance.Windows.ContentWin.Open(Item);
|
||||||
|
return true;
|
||||||
|
case KeyboardKeys.F2:
|
||||||
|
Editor.Instance.Windows.ContentWin.Rename(Item);
|
||||||
|
return true;
|
||||||
|
case KeyboardKeys.Delete:
|
||||||
|
Editor.Instance.Windows.ContentWin.Delete(Item);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.OnKeyDown(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void DoDragDrop()
|
||||||
|
{
|
||||||
|
DoDragDrop(DragItems.GetDragData(Item));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool OnShowTooltip(out string text, out Float2 location, out Rectangle area)
|
||||||
|
{
|
||||||
|
Item.UpdateTooltipText();
|
||||||
|
TooltipText = Item.TooltipText;
|
||||||
|
return base.OnShowTooltip(out text, out location, out area);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
void IContentItemOwner.OnItemDeleted(ContentItem item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
void IContentItemOwner.OnItemRenamed(ContentItem item)
|
||||||
|
{
|
||||||
|
UpdateDisplayedName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
void IContentItemOwner.OnItemReimported(ContentItem item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
void IContentItemOwner.OnItemDispose(ContentItem item)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override int Compare(Control other)
|
||||||
|
{
|
||||||
|
if (other is ContentFolderTreeNode)
|
||||||
|
return 1;
|
||||||
|
if (other is ContentItemTreeNode otherItem)
|
||||||
|
return ApplySortOrder(string.Compare(Text, otherItem.Text, StringComparison.InvariantCulture));
|
||||||
|
return base.Compare(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnDestroy()
|
||||||
|
{
|
||||||
|
Item.RemoveReference(this);
|
||||||
|
base.OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the text of the node.
|
||||||
|
/// </summary>
|
||||||
|
public void UpdateDisplayedName()
|
||||||
|
{
|
||||||
|
var contentWindow = Editor.Instance?.Windows?.ContentWin;
|
||||||
|
var showExtensions = contentWindow?.View?.ShowFileExtensions ?? true;
|
||||||
|
Text = Item.ShowFileExtension || showExtensions ? Item.FileName : Item.ShortName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SortType GetSortType()
|
||||||
|
{
|
||||||
|
return Editor.Instance?.Windows?.ContentWin?.CurrentSortType ?? SortType.AlphabeticOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ApplySortOrder(int result)
|
||||||
|
{
|
||||||
|
return GetSortType() == SortType.AlphabeticReverse ? -result : result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,333 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using FlaxEditor.GUI;
|
|
||||||
using FlaxEditor.GUI.Drag;
|
|
||||||
using FlaxEditor.GUI.Tree;
|
|
||||||
using FlaxEditor.Utilities;
|
|
||||||
using FlaxEngine;
|
|
||||||
using FlaxEngine.GUI;
|
|
||||||
|
|
||||||
namespace FlaxEditor.Content
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Content folder tree node.
|
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="TreeNode" />
|
|
||||||
public class ContentTreeNode : TreeNode
|
|
||||||
{
|
|
||||||
private DragItems _dragOverItems;
|
|
||||||
private List<Rectangle> _highlights;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The folder.
|
|
||||||
/// </summary>
|
|
||||||
protected ContentFolder _folder;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether this node can be deleted.
|
|
||||||
/// </summary>
|
|
||||||
public virtual bool CanDelete => true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether this node can be duplicated.
|
|
||||||
/// </summary>
|
|
||||||
public virtual bool CanDuplicate => true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the content folder item.
|
|
||||||
/// </summary>
|
|
||||||
public ContentFolder Folder => _folder;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the type of the folder.
|
|
||||||
/// </summary>
|
|
||||||
public ContentFolderType FolderType => _folder.FolderType;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if that folder can import/manage scripts.
|
|
||||||
/// </summary>
|
|
||||||
public bool CanHaveScripts => _folder.CanHaveScripts;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if that folder can import/manage assets.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>True if can contain assets for project, otherwise false</returns>
|
|
||||||
public bool CanHaveAssets => _folder.CanHaveAssets;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the parent node.
|
|
||||||
/// </summary>
|
|
||||||
public ContentTreeNode ParentNode => Parent as ContentTreeNode;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the folder path.
|
|
||||||
/// </summary>
|
|
||||||
public string Path => _folder.Path;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the navigation button label.
|
|
||||||
/// </summary>
|
|
||||||
public virtual string NavButtonLabel => _folder.ShortName;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ContentTreeNode"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parent">The parent node.</param>
|
|
||||||
/// <param name="path">The folder path.</param>
|
|
||||||
public ContentTreeNode(ContentTreeNode parent, string path)
|
|
||||||
: this(parent, parent?.FolderType ?? ContentFolderType.Other, path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ContentTreeNode"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parent">The parent node.</param>
|
|
||||||
/// <param name="type">The folder type.</param>
|
|
||||||
/// <param name="path">The folder path.</param>
|
|
||||||
protected ContentTreeNode(ContentTreeNode parent, ContentFolderType type, string path)
|
|
||||||
: base(false, Editor.Instance.Icons.FolderClosed32, Editor.Instance.Icons.FolderOpen32)
|
|
||||||
{
|
|
||||||
_folder = new ContentFolder(type, path, this);
|
|
||||||
Text = _folder.ShortName;
|
|
||||||
if (parent != null)
|
|
||||||
{
|
|
||||||
Folder.ParentFolder = parent.Folder;
|
|
||||||
Parent = parent;
|
|
||||||
}
|
|
||||||
IconColor = Style.Current.Foreground;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Shows the rename popup for the item.
|
|
||||||
/// </summary>
|
|
||||||
public void StartRenaming()
|
|
||||||
{
|
|
||||||
if (!_folder.CanRename)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Start renaming the folder
|
|
||||||
Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(false);
|
|
||||||
var dialog = RenamePopup.Show(this, TextRect, _folder.ShortName, false);
|
|
||||||
dialog.Tag = _folder;
|
|
||||||
dialog.Renamed += popup =>
|
|
||||||
{
|
|
||||||
Editor.Instance.Windows.ContentWin.Rename((ContentFolder)popup.Tag, popup.Text);
|
|
||||||
Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(true);
|
|
||||||
};
|
|
||||||
dialog.Closed += popup => { Editor.Instance.Windows.ContentWin.ScrollingOnTreeView(true); };
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the query search filter.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="filterText">The filter text.</param>
|
|
||||||
public void UpdateFilter(string filterText)
|
|
||||||
{
|
|
||||||
bool noFilter = string.IsNullOrWhiteSpace(filterText);
|
|
||||||
|
|
||||||
// Update itself
|
|
||||||
bool isThisVisible;
|
|
||||||
if (noFilter)
|
|
||||||
{
|
|
||||||
// Clear filter
|
|
||||||
_highlights?.Clear();
|
|
||||||
isThisVisible = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var text = Text;
|
|
||||||
if (QueryFilterHelper.Match(filterText, text, out QueryFilterHelper.Range[] ranges))
|
|
||||||
{
|
|
||||||
// Update highlights
|
|
||||||
if (_highlights == null)
|
|
||||||
_highlights = new List<Rectangle>(ranges.Length);
|
|
||||||
else
|
|
||||||
_highlights.Clear();
|
|
||||||
var style = Style.Current;
|
|
||||||
var font = style.FontSmall;
|
|
||||||
var textRect = TextRect;
|
|
||||||
for (int i = 0; i < ranges.Length; i++)
|
|
||||||
{
|
|
||||||
var start = font.GetCharPosition(text, ranges[i].StartIndex);
|
|
||||||
var end = font.GetCharPosition(text, ranges[i].EndIndex);
|
|
||||||
_highlights.Add(new Rectangle(start.X + textRect.X, textRect.Y, end.X - start.X, textRect.Height));
|
|
||||||
}
|
|
||||||
isThisVisible = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Hide
|
|
||||||
_highlights?.Clear();
|
|
||||||
isThisVisible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update children
|
|
||||||
bool isAnyChildVisible = false;
|
|
||||||
for (int i = 0; i < _children.Count; i++)
|
|
||||||
{
|
|
||||||
if (_children[i] is ContentTreeNode child)
|
|
||||||
{
|
|
||||||
child.UpdateFilter(filterText);
|
|
||||||
isAnyChildVisible |= child.Visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isExpanded = isAnyChildVisible;
|
|
||||||
|
|
||||||
if (isExpanded)
|
|
||||||
{
|
|
||||||
Expand(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Collapse(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Visible = isThisVisible | isAnyChildVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Draw()
|
|
||||||
{
|
|
||||||
base.Draw();
|
|
||||||
|
|
||||||
// Draw all highlights
|
|
||||||
if (_highlights != null)
|
|
||||||
{
|
|
||||||
var style = Style.Current;
|
|
||||||
var color = style.ProgressNormal * 0.6f;
|
|
||||||
for (int i = 0; i < _highlights.Count; i++)
|
|
||||||
Render2D.FillRectangle(_highlights[i], color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void OnDestroy()
|
|
||||||
{
|
|
||||||
// Delete folder item
|
|
||||||
_folder.Dispose();
|
|
||||||
|
|
||||||
base.OnDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
private DragDropEffect GetDragEffect(DragData data)
|
|
||||||
{
|
|
||||||
if (data is DragDataFiles)
|
|
||||||
{
|
|
||||||
if (_folder.CanHaveAssets)
|
|
||||||
return DragDropEffect.Copy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_dragOverItems.HasValidDrag)
|
|
||||||
return DragDropEffect.Move;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DragDropEffect.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ValidateDragItem(ContentItem item)
|
|
||||||
{
|
|
||||||
// Reject itself and any parent
|
|
||||||
return item != _folder && !item.Find(_folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override DragDropEffect OnDragEnterHeader(DragData data)
|
|
||||||
{
|
|
||||||
if (_dragOverItems == null)
|
|
||||||
_dragOverItems = new DragItems(ValidateDragItem);
|
|
||||||
|
|
||||||
_dragOverItems.OnDragEnter(data);
|
|
||||||
return GetDragEffect(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override DragDropEffect OnDragMoveHeader(DragData data)
|
|
||||||
{
|
|
||||||
return GetDragEffect(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void OnDragLeaveHeader()
|
|
||||||
{
|
|
||||||
_dragOverItems.OnDragLeave();
|
|
||||||
base.OnDragLeaveHeader();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override DragDropEffect OnDragDropHeader(DragData data)
|
|
||||||
{
|
|
||||||
var result = DragDropEffect.None;
|
|
||||||
|
|
||||||
// Check if drop element or files
|
|
||||||
if (data is DragDataFiles files)
|
|
||||||
{
|
|
||||||
// Import files
|
|
||||||
Editor.Instance.ContentImporting.Import(files.Files, _folder);
|
|
||||||
result = DragDropEffect.Copy;
|
|
||||||
|
|
||||||
Expand();
|
|
||||||
}
|
|
||||||
else if (_dragOverItems.HasValidDrag)
|
|
||||||
{
|
|
||||||
// Move items
|
|
||||||
Editor.Instance.ContentDatabase.Move(_dragOverItems.Objects, _folder);
|
|
||||||
result = DragDropEffect.Move;
|
|
||||||
|
|
||||||
Expand();
|
|
||||||
}
|
|
||||||
|
|
||||||
_dragOverItems.OnDragDrop();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void DoDragDrop()
|
|
||||||
{
|
|
||||||
DoDragDrop(DragItems.GetDragData(_folder));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void OnLongPress()
|
|
||||||
{
|
|
||||||
Select();
|
|
||||||
|
|
||||||
StartRenaming();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool OnKeyDown(KeyboardKeys key)
|
|
||||||
{
|
|
||||||
if (IsFocused)
|
|
||||||
{
|
|
||||||
switch (key)
|
|
||||||
{
|
|
||||||
case KeyboardKeys.F2:
|
|
||||||
StartRenaming();
|
|
||||||
return true;
|
|
||||||
case KeyboardKeys.Delete:
|
|
||||||
if (Folder.Exists && CanDelete)
|
|
||||||
Editor.Instance.Windows.ContentWin.Delete(Folder);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (RootWindow.GetKey(KeyboardKeys.Control))
|
|
||||||
{
|
|
||||||
switch (key)
|
|
||||||
{
|
|
||||||
case KeyboardKeys.D:
|
|
||||||
if (Folder.Exists && CanDuplicate)
|
|
||||||
Editor.Instance.Windows.ContentWin.Duplicate(Folder);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnKeyDown(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,8 +7,8 @@ namespace FlaxEditor.Content
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Content tree node used for main directories.
|
/// Content tree node used for main directories.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="FlaxEditor.Content.ContentTreeNode" />
|
/// <seealso cref="ContentFolderTreeNode" />
|
||||||
public class MainContentTreeNode : ContentTreeNode
|
public class MainContentFolderTreeNode : ContentFolderTreeNode
|
||||||
{
|
{
|
||||||
private FileSystemWatcher _watcher;
|
private FileSystemWatcher _watcher;
|
||||||
|
|
||||||
@@ -19,12 +19,12 @@ namespace FlaxEditor.Content
|
|||||||
public override bool CanDuplicate => false;
|
public override bool CanDuplicate => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MainContentTreeNode"/> class.
|
/// Initializes a new instance of the <see cref="MainContentFolderTreeNode"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="parent">The parent project.</param>
|
/// <param name="parent">The parent project.</param>
|
||||||
/// <param name="type">The folder type.</param>
|
/// <param name="type">The folder type.</param>
|
||||||
/// <param name="path">The folder path.</param>
|
/// <param name="path">The folder path.</param>
|
||||||
public MainContentTreeNode(ProjectTreeNode parent, ContentFolderType type, string path)
|
public MainContentFolderTreeNode(ProjectFolderTreeNode parent, ContentFolderType type, string path)
|
||||||
: base(parent, type, path)
|
: base(parent, type, path)
|
||||||
{
|
{
|
||||||
_watcher = new FileSystemWatcher(path)
|
_watcher = new FileSystemWatcher(path)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using System;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
namespace FlaxEditor.Content
|
namespace FlaxEditor.Content
|
||||||
@@ -7,8 +8,8 @@ namespace FlaxEditor.Content
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Root tree node for the project workspace.
|
/// Root tree node for the project workspace.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="FlaxEditor.Content.ContentTreeNode" />
|
/// <seealso cref="ContentFolderTreeNode" />
|
||||||
public sealed class ProjectTreeNode : ContentTreeNode
|
public sealed class ProjectFolderTreeNode : ContentFolderTreeNode
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The project/
|
/// The project/
|
||||||
@@ -18,18 +19,18 @@ namespace FlaxEditor.Content
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The project content directory.
|
/// The project content directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MainContentTreeNode Content;
|
public MainContentFolderTreeNode Content;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The project source code directory.
|
/// The project source code directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MainContentTreeNode Source;
|
public MainContentFolderTreeNode Source;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ProjectTreeNode"/> class.
|
/// Initializes a new instance of the <see cref="ProjectFolderTreeNode"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="project">The project.</param>
|
/// <param name="project">The project.</param>
|
||||||
public ProjectTreeNode(ProjectInfo project)
|
public ProjectFolderTreeNode(ProjectInfo project)
|
||||||
: base(null, project.ProjectFolderPath)
|
: base(null, project.ProjectFolderPath)
|
||||||
{
|
{
|
||||||
Project = project;
|
Project = project;
|
||||||
@@ -48,9 +49,29 @@ namespace FlaxEditor.Content
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override int Compare(Control other)
|
public override int Compare(Control other)
|
||||||
{
|
{
|
||||||
// Move the main game project to the top
|
if (other is ProjectFolderTreeNode otherProject)
|
||||||
if (Project.Name == Editor.Instance.GameProject.Name)
|
{
|
||||||
return -1;
|
var gameProject = Editor.Instance.GameProject;
|
||||||
|
var engineProject = Editor.Instance.EngineProject;
|
||||||
|
bool isGame = Project == gameProject;
|
||||||
|
bool isEngine = Project == engineProject;
|
||||||
|
bool otherIsGame = otherProject.Project == gameProject;
|
||||||
|
bool otherIsEngine = otherProject.Project == engineProject;
|
||||||
|
|
||||||
|
// Main game project at the top
|
||||||
|
if (isGame && !otherIsGame)
|
||||||
|
return -1;
|
||||||
|
if (!isGame && otherIsGame)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// Engine project at the bottom (when distinct)
|
||||||
|
if (isEngine && !otherIsEngine)
|
||||||
|
return 1;
|
||||||
|
if (!isEngine && otherIsEngine)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return string.CompareOrdinal(Project.Name, otherProject.Project.Name);
|
||||||
|
}
|
||||||
return base.Compare(other);
|
return base.Compare(other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ namespace FlaxEditor.Content
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Root tree node for the content workspace.
|
/// Root tree node for the content workspace.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="FlaxEditor.Content.ContentTreeNode" />
|
/// <seealso cref="ContentFolderTreeNode" />
|
||||||
public sealed class RootContentTreeNode : ContentTreeNode
|
public sealed class RootContentFolderTreeNode : ContentFolderTreeNode
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RootContentTreeNode"/> class.
|
/// Initializes a new instance of the <see cref="RootContentFolderTreeNode"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RootContentTreeNode()
|
public RootContentFolderTreeNode()
|
||||||
: base(null, string.Empty)
|
: base(null, string.Empty)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,6 +141,11 @@ API_ENUM() enum class BuildPlatform
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
|
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
|
||||||
WindowsARM64 = 15,
|
WindowsARM64 = 15,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Web
|
||||||
|
/// </summary>
|
||||||
|
Web = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -188,6 +193,11 @@ enum class DotNetAOTModes
|
|||||||
/// Use Mono AOT to cross-compile all used C# assemblies into native platform static libraries which can be linked into a single shared library.
|
/// Use Mono AOT to cross-compile all used C# assemblies into native platform static libraries which can be linked into a single shared library.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MonoAOTStatic,
|
MonoAOTStatic,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Target platform doesn't support .NET or it has been disabled.
|
||||||
|
/// </summary>
|
||||||
|
NoDotnet,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform);
|
extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform);
|
||||||
|
|||||||
@@ -69,6 +69,10 @@
|
|||||||
#include "Platform/iOS/iOSPlatformTools.h"
|
#include "Platform/iOS/iOSPlatformTools.h"
|
||||||
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
|
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if PLATFORM_TOOLS_WEB
|
||||||
|
#include "Platform/Web/WebPlatformTools.h"
|
||||||
|
#include "Engine/Platform/Web/WebPlatformSettings.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace GameCookerImpl
|
namespace GameCookerImpl
|
||||||
{
|
{
|
||||||
@@ -151,6 +155,8 @@ const Char* ToString(const BuildPlatform platform)
|
|||||||
return TEXT("iOS ARM64");
|
return TEXT("iOS ARM64");
|
||||||
case BuildPlatform::WindowsARM64:
|
case BuildPlatform::WindowsARM64:
|
||||||
return TEXT("Windows ARM64");
|
return TEXT("Windows ARM64");
|
||||||
|
case BuildPlatform::Web:
|
||||||
|
return TEXT("Web");
|
||||||
default:
|
default:
|
||||||
return TEXT("");
|
return TEXT("");
|
||||||
}
|
}
|
||||||
@@ -183,6 +189,8 @@ const Char* ToString(const DotNetAOTModes mode)
|
|||||||
return TEXT("MonoAOTDynamic");
|
return TEXT("MonoAOTDynamic");
|
||||||
case DotNetAOTModes::MonoAOTStatic:
|
case DotNetAOTModes::MonoAOTStatic:
|
||||||
return TEXT("MonoAOTStatic");
|
return TEXT("MonoAOTStatic");
|
||||||
|
case DotNetAOTModes::NoDotnet:
|
||||||
|
return TEXT("NoDotnet");
|
||||||
default:
|
default:
|
||||||
return TEXT("");
|
return TEXT("");
|
||||||
}
|
}
|
||||||
@@ -307,6 +315,10 @@ void CookingData::GetBuildPlatformName(const Char*& platform, const Char*& archi
|
|||||||
platform = TEXT("Windows");
|
platform = TEXT("Windows");
|
||||||
architecture = TEXT("ARM64");
|
architecture = TEXT("ARM64");
|
||||||
break;
|
break;
|
||||||
|
case BuildPlatform::Web:
|
||||||
|
platform = TEXT("Web");
|
||||||
|
architecture = TEXT("x86");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(Fatal, "Unknown or unsupported build platform.");
|
LOG(Fatal, "Unknown or unsupported build platform.");
|
||||||
}
|
}
|
||||||
@@ -461,6 +473,11 @@ PlatformTools* GameCooker::GetTools(BuildPlatform platform)
|
|||||||
case BuildPlatform::iOSARM64:
|
case BuildPlatform::iOSARM64:
|
||||||
result = New<iOSPlatformTools>();
|
result = New<iOSPlatformTools>();
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#if PLATFORM_TOOLS_WEB
|
||||||
|
case BuildPlatform::Web:
|
||||||
|
result = New<WebPlatformTools>();
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
Tools.Add(platform, result);
|
Tools.Add(platform, result);
|
||||||
@@ -518,7 +535,8 @@ bool GameCooker::Build(BuildPlatform platform, BuildConfiguration configuration,
|
|||||||
{
|
{
|
||||||
Function<int32()> f;
|
Function<int32()> f;
|
||||||
f.Bind(ThreadFunction);
|
f.Bind(ThreadFunction);
|
||||||
const auto thread = ThreadSpawner::Start(f, GameCookerServiceInstance.Name, ThreadPriority::Highest);
|
uint32 stackSize = 4 * 1024 * 1024; // Larger stack
|
||||||
|
const auto thread = ThreadSpawner::Start(f, GameCookerServiceInstance.Name, ThreadPriority::Highest, stackSize);
|
||||||
if (thread == nullptr)
|
if (thread == nullptr)
|
||||||
{
|
{
|
||||||
GameCookerImpl::IsRunning = false;
|
GameCookerImpl::IsRunning = false;
|
||||||
@@ -604,6 +622,9 @@ void GameCooker::GetCurrentPlatform(PlatformType& platform, BuildPlatform& build
|
|||||||
case PlatformType::iOS:
|
case PlatformType::iOS:
|
||||||
buildPlatform = BuildPlatform::iOSARM64;
|
buildPlatform = BuildPlatform::iOSARM64;
|
||||||
break;
|
break;
|
||||||
|
case PlatformType::Web:
|
||||||
|
buildPlatform = BuildPlatform::Web;
|
||||||
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ namespace FlaxEditor
|
|||||||
case BuildPlatform.MacOSARM64:
|
case BuildPlatform.MacOSARM64:
|
||||||
case BuildPlatform.MacOSx64: return PlatformType.Mac;
|
case BuildPlatform.MacOSx64: return PlatformType.Mac;
|
||||||
case BuildPlatform.iOSARM64: return PlatformType.iOS;
|
case BuildPlatform.iOSARM64: return PlatformType.iOS;
|
||||||
|
case BuildPlatform.Web: return PlatformType.Web;
|
||||||
default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null);
|
default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ Array<byte> AndroidPlatformTools::SaveCache(CookingData& data, IBuildCache* cach
|
|||||||
result.Add((const byte*)&platformCache, sizeof(platformCache));
|
result.Add((const byte*)&platformCache, sizeof(platformCache));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidPlatformTools::OnBuildStarted(CookingData& data)
|
void AndroidPlatformTools::OnBuildStarted(CookingData& data)
|
||||||
{
|
{
|
||||||
// Adjust the cooking output folder to be located inside the Gradle assets directory
|
// Adjust the cooking output folder to be located inside the Gradle assets directory
|
||||||
@@ -411,7 +412,6 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
|
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
270
Source/Editor/Cooker/Platform/Web/WebPlatformTools.cpp
Normal file
270
Source/Editor/Cooker/Platform/Web/WebPlatformTools.cpp
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
#if PLATFORM_TOOLS_WEB
|
||||||
|
|
||||||
|
#include "WebPlatformTools.h"
|
||||||
|
#include "Engine/Platform/File.h"
|
||||||
|
#include "Engine/Platform/FileSystem.h"
|
||||||
|
#include "Engine/Platform/CreateProcessSettings.h"
|
||||||
|
#include "Engine/Platform/Web/WebPlatformSettings.h"
|
||||||
|
#include "Engine/Core/Types/Span.h"
|
||||||
|
#include "Engine/Core/Math/Vector2.h"
|
||||||
|
#include "Engine/Core/Config/GameSettings.h"
|
||||||
|
#include "Engine/Core/Config/BuildSettings.h"
|
||||||
|
#include "Engine/Content/Content.h"
|
||||||
|
#include "Engine/Content/JsonAsset.h"
|
||||||
|
#include "Engine/Graphics/PixelFormatExtensions.h"
|
||||||
|
#include "Engine/Graphics/Textures/TextureBase.h"
|
||||||
|
#include "Editor/Cooker/GameCooker.h"
|
||||||
|
|
||||||
|
IMPLEMENT_SETTINGS_GETTER(WebPlatformSettings, WebPlatform);
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct WebPlatformCache
|
||||||
|
{
|
||||||
|
WebPlatformSettings::TextureCompression TexturesCompression;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const Char* WebPlatformTools::GetDisplayName() const
|
||||||
|
{
|
||||||
|
return TEXT("Web");
|
||||||
|
}
|
||||||
|
|
||||||
|
const Char* WebPlatformTools::GetName() const
|
||||||
|
{
|
||||||
|
return TEXT("Web");
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformType WebPlatformTools::GetPlatform() const
|
||||||
|
{
|
||||||
|
return PlatformType::Web;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchitectureType WebPlatformTools::GetArchitecture() const
|
||||||
|
{
|
||||||
|
return ArchitectureType::x86;
|
||||||
|
}
|
||||||
|
|
||||||
|
DotNetAOTModes WebPlatformTools::UseAOT() const
|
||||||
|
{
|
||||||
|
return DotNetAOTModes::NoDotnet;
|
||||||
|
}
|
||||||
|
|
||||||
|
PixelFormat WebPlatformTools::GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format)
|
||||||
|
{
|
||||||
|
const auto platformSettings = WebPlatformSettings::Get();
|
||||||
|
const auto uncompressed = PixelFormatExtensions::FindUncompressedFormat(format);
|
||||||
|
switch (platformSettings->TexturesCompression)
|
||||||
|
{
|
||||||
|
case WebPlatformSettings::TextureCompression::Uncompressed:
|
||||||
|
return uncompressed;
|
||||||
|
case WebPlatformSettings::TextureCompression::BC:
|
||||||
|
return format;
|
||||||
|
case WebPlatformSettings::TextureCompression::ASTC:
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case PixelFormat::BC4_SNorm:
|
||||||
|
return PixelFormat::R8_SNorm;
|
||||||
|
case PixelFormat::BC5_SNorm:
|
||||||
|
return PixelFormat::R16G16_SNorm;
|
||||||
|
case PixelFormat::BC6H_Typeless:
|
||||||
|
case PixelFormat::BC6H_Uf16:
|
||||||
|
case PixelFormat::BC6H_Sf16:
|
||||||
|
case PixelFormat::BC7_Typeless:
|
||||||
|
case PixelFormat::BC7_UNorm:
|
||||||
|
case PixelFormat::BC7_UNorm_sRGB:
|
||||||
|
return PixelFormat::R16G16B16A16_Float; // TODO: ASTC HDR
|
||||||
|
default:
|
||||||
|
return PixelFormatExtensions::IsSRGB(format) ? PixelFormat::ASTC_6x6_UNorm_sRGB : PixelFormat::ASTC_6x6_UNorm;
|
||||||
|
}
|
||||||
|
case WebPlatformSettings::TextureCompression::Basis:
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case PixelFormat::BC7_Typeless:
|
||||||
|
case PixelFormat::BC7_UNorm:
|
||||||
|
case PixelFormat::BC7_UNorm_sRGB:
|
||||||
|
return PixelFormat::R16G16B16A16_Float; // Basic Universal doesn't support alpha in BC7 (and it can be loaded only from LDR formats)
|
||||||
|
default:
|
||||||
|
if (uncompressed != format && texture->Size().MinValue() >= 16)
|
||||||
|
return PixelFormat::Basis;
|
||||||
|
return uncompressed;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebPlatformTools::LoadCache(CookingData& data, IBuildCache* cache, const Span<byte>& bytes)
|
||||||
|
{
|
||||||
|
const auto platformSettings = WebPlatformSettings::Get();
|
||||||
|
bool invalidTextures = true;
|
||||||
|
if (bytes.Length() == sizeof(WebPlatformCache))
|
||||||
|
{
|
||||||
|
auto* platformCache = (WebPlatformCache*)bytes.Get();
|
||||||
|
invalidTextures = platformCache->TexturesCompression != platformSettings->TexturesCompression;
|
||||||
|
}
|
||||||
|
if (invalidTextures)
|
||||||
|
{
|
||||||
|
LOG(Info, "{0} option has been modified.", TEXT("TexturesQuality"));
|
||||||
|
cache->InvalidateCacheTextures();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<byte> WebPlatformTools::SaveCache(CookingData& data, IBuildCache* cache)
|
||||||
|
{
|
||||||
|
const auto platformSettings = WebPlatformSettings::Get();
|
||||||
|
WebPlatformCache platformCache;
|
||||||
|
platformCache.TexturesCompression = platformSettings->TexturesCompression;
|
||||||
|
Array<byte> result;
|
||||||
|
result.Add((const byte*)&platformCache, sizeof(platformCache));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebPlatformTools::IsNativeCodeFile(CookingData& data, const String& file)
|
||||||
|
{
|
||||||
|
String extension = FileSystem::GetExtension(file);
|
||||||
|
return extension.IsEmpty() || extension == TEXT("html") || extension == TEXT("js") || extension == TEXT("wasm");
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebPlatformTools::OnBuildStarted(CookingData& data)
|
||||||
|
{
|
||||||
|
// Adjust the cooking output folder for the data files so file_packager tool can compress and output final data inside the cooker output folder
|
||||||
|
data.DataOutputPath = data.CacheDirectory / TEXT("Files");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebPlatformTools::OnPostProcess(CookingData& data)
|
||||||
|
{
|
||||||
|
const auto gameSettings = GameSettings::Get();
|
||||||
|
const auto platformSettings = WebPlatformSettings::Get();
|
||||||
|
const auto platformDataPath = data.GetPlatformBinariesRoot();
|
||||||
|
|
||||||
|
// Get name of the output binary (JavaScript and WebAssembly files match)
|
||||||
|
String gameJs;
|
||||||
|
{
|
||||||
|
Array<String> files;
|
||||||
|
FileSystem::DirectoryGetFiles(files, data.OriginalOutputPath, TEXT("*"), DirectorySearchOption::TopDirectoryOnly);
|
||||||
|
for (const String& file : files)
|
||||||
|
{
|
||||||
|
if (file.EndsWith(TEXT(".js")))
|
||||||
|
{
|
||||||
|
String outputWasm = String(StringUtils::GetPathWithoutExtension(file)) + TEXT(".wasm");
|
||||||
|
if (files.Contains(outputWasm))
|
||||||
|
{
|
||||||
|
gameJs = file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gameJs.IsEmpty())
|
||||||
|
{
|
||||||
|
data.Error(TEXT("Failed to find the main JavaScript for the output game"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move .wasm assemblies into the data files in order for dlopen to work (blocking)
|
||||||
|
{
|
||||||
|
Array<String> files;
|
||||||
|
FileSystem::DirectoryGetFiles(files, data.OriginalOutputPath, TEXT("*.wasm"), DirectorySearchOption::AllDirectories);
|
||||||
|
StringView gameWasm = StringUtils::GetFileNameWithoutExtension(gameJs);
|
||||||
|
for (const String& file : files)
|
||||||
|
{
|
||||||
|
if (StringUtils::GetFileNameWithoutExtension(file) == gameWasm)
|
||||||
|
continue; // Skip the main game module
|
||||||
|
FileSystem::MoveFile(data.DataOutputPath / StringUtils::GetFileName(file), file, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pack data files into a single file using Emscripten's file_packager tool
|
||||||
|
{
|
||||||
|
CreateProcessSettings procSettings;
|
||||||
|
String emscriptenSdk = TEXT("EMSDK");
|
||||||
|
Platform::GetEnvironmentVariable(emscriptenSdk, emscriptenSdk);
|
||||||
|
procSettings.FileName = emscriptenSdk / TEXT("upstream/emscripten/tools/file_packager");
|
||||||
|
#if PLATFORM_WIN32
|
||||||
|
procSettings.FileName += TEXT(".bat");
|
||||||
|
#endif
|
||||||
|
procSettings.Arguments = String::Format(TEXT("files.data --preload \"{}@/\" --lz4 --js-output=files.js"), data.DataOutputPath);
|
||||||
|
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
||||||
|
const int32 result = Platform::CreateProcess(procSettings);
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
if (!FileSystem::FileExists(procSettings.FileName))
|
||||||
|
data.Error(TEXT("Missing file_packager.bat. Ensure Emscripten SDK installation is valid and 'EMSDK' environment variable points to it."));
|
||||||
|
data.Error(String::Format(TEXT("Failed to package project files (result code: {0}). See log for more info."), result));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy icon file
|
||||||
|
{
|
||||||
|
String dstIcon = data.OriginalOutputPath / TEXT("favicon.ico");
|
||||||
|
if (!FileSystem::FileExists(dstIcon))
|
||||||
|
FileSystem::CopyFile(dstIcon, platformDataPath / TEXT("favicon.ico"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy custom HTMl template
|
||||||
|
auto customHtml = platformSettings->CustomHtml.TrimTrailing();
|
||||||
|
if (customHtml.HasChars())
|
||||||
|
{
|
||||||
|
FileSystem::CopyFile(data.OriginalOutputPath / TEXT("FlaxGame.html"), customHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename game website main HTML file to match the most common name used by web servers (index.html)
|
||||||
|
FileSystem::MoveFile(data.OriginalOutputPath / TEXT("index.html"), data.OriginalOutputPath / TEXT("FlaxGame.html"), true);
|
||||||
|
|
||||||
|
// Insert packaged file system with game data
|
||||||
|
{
|
||||||
|
String gameJsText;
|
||||||
|
if (File::ReadAllText(gameJs, gameJsText))
|
||||||
|
{
|
||||||
|
data.Error(String::Format(TEXT("Failed to load file '{}'"), gameJs));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const String filesIncludeBegin = TEXT("// include: files.js");
|
||||||
|
const String filesIncludeEnd = TEXT("// end include: files.js");
|
||||||
|
String fileJs = data.OriginalOutputPath / TEXT("files.js");
|
||||||
|
if (!gameJsText.Contains(filesIncludeBegin))
|
||||||
|
{
|
||||||
|
// Insert generated files.js into the main game file after the minimum_runtime_check.js include
|
||||||
|
String fileJsText;
|
||||||
|
if (File::ReadAllText(fileJs, fileJsText))
|
||||||
|
{
|
||||||
|
data.Error(String::Format(TEXT("Failed to load file '{}'"), fileJs));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const String insertPrefixLocation = TEXT("// end include: minimum_runtime_check.js");
|
||||||
|
int32 location = gameJsText.Find(insertPrefixLocation);
|
||||||
|
if (location != -1)
|
||||||
|
{
|
||||||
|
location += insertPrefixLocation.Length() + 1;
|
||||||
|
fileJsText = filesIncludeBegin + TEXT("\n") + fileJsText + TEXT("\n") + filesIncludeEnd + TEXT("\n");
|
||||||
|
gameJsText.Insert(location, fileJsText);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Comments are missing in Release when JS/HTML are minified
|
||||||
|
fileJsText.Insert(0, filesIncludeBegin);
|
||||||
|
fileJsText.Insert(0, TEXT("\n"));
|
||||||
|
gameJsText.Insert(0, fileJsText);
|
||||||
|
}
|
||||||
|
File::WriteAllText(gameJs, gameJsText, Encoding::UTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the generated files.js as it's now included in the main game JS file
|
||||||
|
FileSystem::DeleteFile(fileJs);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto buildSettings = BuildSettings::Get();
|
||||||
|
if (buildSettings->SkipPackaging)
|
||||||
|
return false;
|
||||||
|
GameCooker::PackageFiles();
|
||||||
|
|
||||||
|
LOG(Info, "Output website size: {0} MB", FileSystem::GetDirectorySize(data.OriginalOutputPath) / 1024 / 1024);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
29
Source/Editor/Cooker/Platform/Web/WebPlatformTools.h
Normal file
29
Source/Editor/Cooker/Platform/Web/WebPlatformTools.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if PLATFORM_TOOLS_WEB
|
||||||
|
|
||||||
|
#include "../../PlatformTools.h"
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Web platform support tools.
|
||||||
|
/// </summary>
|
||||||
|
class WebPlatformTools : public PlatformTools
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// [PlatformTools]
|
||||||
|
const Char* GetDisplayName() const override;
|
||||||
|
const Char* GetName() const override;
|
||||||
|
PlatformType GetPlatform() const override;
|
||||||
|
ArchitectureType GetArchitecture() const override;
|
||||||
|
DotNetAOTModes UseAOT() const override;
|
||||||
|
PixelFormat GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format) override;
|
||||||
|
void LoadCache(CookingData& data, IBuildCache* cache, const Span<byte>& bytes) override;
|
||||||
|
Array<byte> SaveCache(CookingData& data, IBuildCache* cache) override;
|
||||||
|
bool IsNativeCodeFile(CookingData& data, const String& file) override;
|
||||||
|
void OnBuildStarted(CookingData& data) override;
|
||||||
|
bool OnPostProcess(CookingData& data) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -572,6 +572,14 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
|
|||||||
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
|
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if PLATFORM_TOOLS_WEB
|
||||||
|
case BuildPlatform::Web:
|
||||||
|
{
|
||||||
|
const char* platformDefineName = "PLATFORM_WEB";
|
||||||
|
COMPILE_PROFILE(WebGPU, SHADER_FILE_CHUNK_INTERNAL_GENERIC_CACHE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@@ -734,37 +742,8 @@ bool ProcessTextureBase(CookAssetsStep::AssetCookData& data)
|
|||||||
{
|
{
|
||||||
auto chunk = New<FlaxChunk>();
|
auto chunk = New<FlaxChunk>();
|
||||||
data.InitData.Header.Chunks[mipIndex] = chunk;
|
data.InitData.Header.Chunks[mipIndex] = chunk;
|
||||||
|
if (TextureTool::WriteTextureData(chunk->Data, *textureData, mipIndex))
|
||||||
// Calculate the texture data storage layout
|
return true;
|
||||||
uint32 rowPitch, slicePitch;
|
|
||||||
const int32 mipWidth = Math::Max(1, textureData->Width >> mipIndex);
|
|
||||||
const int32 mipHeight = Math::Max(1, textureData->Height >> mipIndex);
|
|
||||||
RenderTools::ComputePitch(textureData->Format, mipWidth, mipHeight, rowPitch, slicePitch);
|
|
||||||
chunk->Data.Allocate(slicePitch * textureData->GetArraySize());
|
|
||||||
|
|
||||||
// Copy array slices into mip data (sequential)
|
|
||||||
for (int32 arrayIndex = 0; arrayIndex < textureData->Items.Count(); arrayIndex++)
|
|
||||||
{
|
|
||||||
auto& mipData = textureData->Items[arrayIndex].Mips[mipIndex];
|
|
||||||
byte* src = mipData.Data.Get();
|
|
||||||
byte* dst = chunk->Data.Get() + (slicePitch * arrayIndex);
|
|
||||||
|
|
||||||
// Faster path if source and destination data layout matches
|
|
||||||
if (rowPitch == mipData.RowPitch && slicePitch == mipData.DepthPitch)
|
|
||||||
{
|
|
||||||
Platform::MemoryCopy(dst, src, slicePitch);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto copyRowSize = Math::Min(mipData.RowPitch, rowPitch);
|
|
||||||
for (uint32 line = 0; line < mipData.Lines; line++)
|
|
||||||
{
|
|
||||||
Platform::MemoryCopy(dst, src, copyRowSize);
|
|
||||||
src += mipData.RowPitch;
|
|
||||||
dst += rowPitch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone any custom asset chunks (eg. sprite atlas data, mips are in 0-13 chunks)
|
// Clone any custom asset chunks (eg. sprite atlas data, mips are in 0-13 chunks)
|
||||||
|
|||||||
@@ -39,17 +39,23 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
String dstDotnet = data.DataOutputPath / TEXT("Dotnet");
|
String dstDotnet = data.DataOutputPath / TEXT("Dotnet");
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
const bool usAOT = aotMode != DotNetAOTModes::None;
|
const bool usAOT = aotMode != DotNetAOTModes::None && aotMode != DotNetAOTModes::NoDotnet;
|
||||||
if (usAOT)
|
if (usAOT)
|
||||||
{
|
{
|
||||||
// Deploy Dotnet files into intermediate cooking directory for AOT
|
// Deploy Dotnet files into intermediate cooking directory for AOT
|
||||||
FileSystem::DeleteDirectory(dstDotnet);
|
FileSystem::DeleteDirectory(dstDotnet);
|
||||||
dstDotnet = data.ManagedCodeOutputPath;
|
dstDotnet = data.ManagedCodeOutputPath;
|
||||||
}
|
}
|
||||||
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
if (aotMode == DotNetAOTModes::NoDotnet)
|
||||||
|
{
|
||||||
|
// No .NET
|
||||||
|
FileSystem::DeleteDirectory(dstDotnet);
|
||||||
|
}
|
||||||
|
else if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
||||||
{
|
{
|
||||||
// Use system-installed .NET Runtime
|
// Use system-installed .NET Runtime
|
||||||
FileSystem::DeleteDirectory(dstDotnet);
|
FileSystem::DeleteDirectory(dstDotnet);
|
||||||
|
LOG(Info, "Not using .NET Runtime");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
||||||
{
|
{
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
if (aotMode == DotNetAOTModes::None || EnumHasAllFlags(data.Options, BuildOptions::NoCook))
|
if (aotMode == DotNetAOTModes::None ||
|
||||||
|
aotMode == DotNetAOTModes::NoDotnet ||
|
||||||
|
EnumHasAllFlags(data.Options, BuildOptions::NoCook))
|
||||||
return;
|
return;
|
||||||
const auto& buildSettings = *BuildSettings::Get();
|
const auto& buildSettings = *BuildSettings::Get();
|
||||||
|
|
||||||
@@ -49,7 +51,8 @@ void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
|||||||
bool PrecompileAssembliesStep::Perform(CookingData& data)
|
bool PrecompileAssembliesStep::Perform(CookingData& data)
|
||||||
{
|
{
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
if (aotMode == DotNetAOTModes::None)
|
if (aotMode == DotNetAOTModes::None ||
|
||||||
|
aotMode == DotNetAOTModes::NoDotnet)
|
||||||
return false;
|
return false;
|
||||||
const auto& buildSettings = *BuildSettings::Get();
|
const auto& buildSettings = *BuildSettings::Get();
|
||||||
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
private readonly List<CustomEditor> _children = new List<CustomEditor>();
|
private readonly List<CustomEditor> _children = new List<CustomEditor>();
|
||||||
private ValueContainer _values;
|
private ValueContainer _values;
|
||||||
private bool _isSetBlocked;
|
private bool _isSetBlocked;
|
||||||
|
private bool _isRebuilding;
|
||||||
private bool _skipChildrenRefresh;
|
private bool _skipChildrenRefresh;
|
||||||
private bool _hasValueDirty;
|
private bool _hasValueDirty;
|
||||||
private bool _rebuildOnRefresh;
|
private bool _rebuildOnRefresh;
|
||||||
@@ -178,7 +179,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
public void RebuildLayout()
|
public void RebuildLayout()
|
||||||
{
|
{
|
||||||
// Skip rebuilding during init
|
// Skip rebuilding during init
|
||||||
if (CurrentCustomEditor == this)
|
if (CurrentCustomEditor == this || _isRebuilding)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Special case for root objects to run normal layout build
|
// Special case for root objects to run normal layout build
|
||||||
@@ -197,6 +198,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
_parent?.RebuildLayout();
|
_parent?.RebuildLayout();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_isRebuilding = true;
|
||||||
var control = layout.ContainerControl;
|
var control = layout.ContainerControl;
|
||||||
var parent = _parent;
|
var parent = _parent;
|
||||||
var parentScrollV = (_presenter?.Panel.Parent as Panel)?.VScrollBar?.Value ?? -1;
|
var parentScrollV = (_presenter?.Panel.Parent as Panel)?.VScrollBar?.Value ?? -1;
|
||||||
@@ -216,6 +218,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
// Restore scroll value
|
// Restore scroll value
|
||||||
if (parentScrollV > -1 && _presenter != null && _presenter.Panel.Parent is Panel panel && panel.VScrollBar != null)
|
if (parentScrollV > -1 && _presenter != null && _presenter.Panel.Parent is Panel panel && panel.VScrollBar != null)
|
||||||
panel.VScrollBar.Value = parentScrollV;
|
panel.VScrollBar.Value = parentScrollV;
|
||||||
|
_isRebuilding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -55,9 +55,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
{
|
{
|
||||||
// TODO: consider editing more than one instance of the same prefab asset at once
|
// TODO: consider editing more than one instance of the same prefab asset at once
|
||||||
|
|
||||||
var prefab = FlaxEngine.Content.LoadAsync<Prefab>(actor.PrefabID);
|
var prefab = FlaxEngine.Content.Load<Prefab>(actor.PrefabID);
|
||||||
// TODO: don't stall here?
|
if (prefab)
|
||||||
if (prefab && !prefab.WaitForLoaded())
|
|
||||||
{
|
{
|
||||||
var prefabObjectId = actor.PrefabObjectID;
|
var prefabObjectId = actor.PrefabObjectID;
|
||||||
var prefabInstance = prefab.GetDefaultInstance(ref prefabObjectId);
|
var prefabInstance = prefab.GetDefaultInstance(ref prefabObjectId);
|
||||||
@@ -203,7 +202,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
//Presenter.BuildLayoutOnUpdate();
|
//Presenter.BuildLayoutOnUpdate();
|
||||||
|
|
||||||
// Better way is to just update the reference value using the new default instance of the prefab, created after changes apply
|
// Better way is to just update the reference value using the new default instance of the prefab, created after changes apply
|
||||||
if (Values != null && prefab && !prefab.WaitForLoaded())
|
if (Values != null && (Actor)Values[0] && prefab && !prefab.WaitForLoaded())
|
||||||
{
|
{
|
||||||
var actor = (Actor)Values[0];
|
var actor = (Actor)Values[0];
|
||||||
var prefabObjectId = actor.PrefabObjectID;
|
var prefabObjectId = actor.PrefabObjectID;
|
||||||
|
|||||||
@@ -103,11 +103,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
var actors = ScriptsEditor.ParentEditor.Values;
|
var actors = ScriptsEditor.ParentEditor.Values;
|
||||||
foreach (var a in actors)
|
foreach (var a in actors)
|
||||||
{
|
{
|
||||||
if (a.GetType() != requireActor.RequiredType)
|
if (a.GetType() == requireActor.RequiredType)
|
||||||
{
|
continue;
|
||||||
item.Enabled = false;
|
if (requireActor.IncludeInheritedTypes && a.GetType().IsSubclassOf(requireActor.RequiredType))
|
||||||
break;
|
continue;
|
||||||
}
|
item.Enabled = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cm.AddItem(item);
|
cm.AddItem(item);
|
||||||
@@ -739,6 +740,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
|
var style = FlaxEngine.GUI.Style.Current;
|
||||||
|
|
||||||
// Area for drag&drop scripts
|
// Area for drag&drop scripts
|
||||||
var dragArea = layout.CustomContainer<DragAreaControl>();
|
var dragArea = layout.CustomContainer<DragAreaControl>();
|
||||||
dragArea.CustomControl.ScriptsEditor = this;
|
dragArea.CustomControl.ScriptsEditor = this;
|
||||||
@@ -800,17 +803,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
bool hasAllRequirements = true;
|
bool hasAllRequirements = true;
|
||||||
if (scriptType.HasAttribute(typeof(RequireScriptAttribute), false))
|
if (scriptType.HasAttribute(typeof(RequireScriptAttribute), false))
|
||||||
{
|
{
|
||||||
RequireScriptAttribute scriptAttribute = null;
|
var attribute = (RequireScriptAttribute)scriptType.GetAttributes(false).FirstOrDefault(x => x is RequireScriptAttribute);
|
||||||
foreach (var e in scriptType.GetAttributes(false))
|
if (attribute != null)
|
||||||
{
|
{
|
||||||
if (e is not RequireScriptAttribute requireScriptAttribute)
|
foreach (var type in attribute.RequiredTypes)
|
||||||
continue;
|
|
||||||
scriptAttribute = requireScriptAttribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scriptAttribute != null)
|
|
||||||
{
|
|
||||||
foreach (var type in scriptAttribute.RequiredTypes)
|
|
||||||
{
|
{
|
||||||
if (!type.IsSubclassOf(typeof(Script)))
|
if (!type.IsSubclassOf(typeof(Script)))
|
||||||
continue;
|
continue;
|
||||||
@@ -825,19 +821,11 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
if (scriptType.HasAttribute(typeof(RequireActorAttribute), false))
|
if (scriptType.HasAttribute(typeof(RequireActorAttribute), false))
|
||||||
{
|
{
|
||||||
RequireActorAttribute attribute = null;
|
var attribute = (RequireActorAttribute)scriptType.GetAttributes(false).FirstOrDefault(x => x is RequireActorAttribute);
|
||||||
foreach (var e in scriptType.GetAttributes(false))
|
|
||||||
{
|
|
||||||
if (e is not RequireActorAttribute requireActorAttribute)
|
|
||||||
continue;
|
|
||||||
attribute = requireActorAttribute;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribute != null)
|
if (attribute != null)
|
||||||
{
|
{
|
||||||
var actor = script.Actor;
|
var actor = script.Actor;
|
||||||
if (actor.GetType() != attribute.RequiredType && !actor.GetType().IsSubclassOf(attribute.RequiredType))
|
if (actor.GetType() != attribute.RequiredType && (attribute.IncludeInheritedTypes && !actor.GetType().IsSubclassOf(attribute.RequiredType)))
|
||||||
{
|
{
|
||||||
Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(scriptType.Name)}` on `{script.Actor}` is missing a required Actor of type `{attribute.RequiredType}`.");
|
Editor.LogWarning($"`{Utilities.Utils.GetPropertyNameUI(scriptType.Name)}` on `{script.Actor}` is missing a required Actor of type `{attribute.RequiredType}`.");
|
||||||
hasAllRequirements = false;
|
hasAllRequirements = false;
|
||||||
@@ -850,7 +838,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
var title = Utilities.Utils.GetPropertyNameUI(scriptType.Name);
|
var title = Utilities.Utils.GetPropertyNameUI(scriptType.Name);
|
||||||
var group = layout.Group(title, editor);
|
var group = layout.Group(title, editor);
|
||||||
if (!hasAllRequirements)
|
if (!hasAllRequirements)
|
||||||
group.Panel.HeaderTextColor = FlaxEngine.GUI.Style.Current.Statusbar.Failed;
|
group.Panel.HeaderTextColor = style.Statusbar.Failed;
|
||||||
if ((Presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
if ((Presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
||||||
{
|
{
|
||||||
if (Editor.Instance.ProjectCache.IsGroupToggled(title))
|
if (Editor.Instance.ProjectCache.IsGroupToggled(title))
|
||||||
@@ -863,9 +851,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
group.Panel.Open();
|
group.Panel.Open();
|
||||||
|
|
||||||
// Customize
|
// Customize
|
||||||
|
float totalHeaderButtonsOffset = 0f;
|
||||||
group.Panel.TooltipText = Editor.Instance.CodeDocs.GetTooltip(scriptType);
|
group.Panel.TooltipText = Editor.Instance.CodeDocs.GetTooltip(scriptType);
|
||||||
if (script.HasPrefabLink)
|
if (script.HasPrefabLink)
|
||||||
group.Panel.HeaderTextColor = FlaxEngine.GUI.Style.Current.ProgressNormal;
|
group.Panel.HeaderTextColor = style.ProgressNormal;
|
||||||
|
|
||||||
// Add toggle button to the group
|
// Add toggle button to the group
|
||||||
var headerHeight = group.Panel.HeaderHeight;
|
var headerHeight = group.Panel.HeaderHeight;
|
||||||
@@ -889,7 +878,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
TooltipText = "Script reference.",
|
TooltipText = "Script reference.",
|
||||||
AutoFocus = true,
|
AutoFocus = true,
|
||||||
IsScrollable = false,
|
IsScrollable = false,
|
||||||
Color = FlaxEngine.GUI.Style.Current.ForegroundGrey,
|
Color = style.ForegroundGrey,
|
||||||
Parent = group.Panel,
|
Parent = group.Panel,
|
||||||
Bounds = new Rectangle(scriptToggle.Right, 0.5f, headerHeight, headerHeight),
|
Bounds = new Rectangle(scriptToggle.Right, 0.5f, headerHeight, headerHeight),
|
||||||
Margin = new Margin(1),
|
Margin = new Margin(1),
|
||||||
@@ -908,10 +897,35 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
var settingsButton = group.AddSettingsButton();
|
var settingsButton = group.AddSettingsButton();
|
||||||
settingsButton.Tag = script;
|
settingsButton.Tag = script;
|
||||||
settingsButton.Clicked += OnSettingsButtonClicked;
|
settingsButton.Clicked += OnSettingsButtonClicked;
|
||||||
|
totalHeaderButtonsOffset += settingsButton.Width + FlaxEditor.Utilities.Constants.UIMargin;
|
||||||
|
|
||||||
|
// Add script obsolete icon to the group
|
||||||
|
if (scriptType.HasAttribute(typeof(ObsoleteAttribute), false))
|
||||||
|
{
|
||||||
|
var attribute = (ObsoleteAttribute)scriptType.GetAttributes(false).First(x => x is ObsoleteAttribute);
|
||||||
|
var tooltip = "Script marked as obsolete." +
|
||||||
|
(string.IsNullOrEmpty(attribute.Message) ? "" : $"\n{attribute.Message}") +
|
||||||
|
(string.IsNullOrEmpty(attribute.DiagnosticId) ? "" : $"\n{attribute.DiagnosticId}");
|
||||||
|
var obsoleteButton = group.AddHeaderButton(tooltip, totalHeaderButtonsOffset, Editor.Instance.Icons.Info32);
|
||||||
|
obsoleteButton.Color = Color.Orange;
|
||||||
|
obsoleteButton.MouseOverColor = Color.DarkOrange;
|
||||||
|
totalHeaderButtonsOffset += obsoleteButton.Width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show visual indicator if script only exists in prefab instance and is not part of the prefab
|
||||||
|
bool isPrefabActor = scripts.Any(s => s.Actor.HasPrefabLink);
|
||||||
|
if (isPrefabActor && script.PrefabID == Guid.Empty)
|
||||||
|
{
|
||||||
|
var prefabInstanceButton = group.AddHeaderButton("Script only exists in this prefab instance.", totalHeaderButtonsOffset, Editor.Instance.Icons.Add32);
|
||||||
|
prefabInstanceButton.Color = style.ProgressNormal;
|
||||||
|
prefabInstanceButton.MouseOverColor = style.ProgressNormal * 0.9f;
|
||||||
|
totalHeaderButtonsOffset += prefabInstanceButton.Width;
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust margin to not overlap with other ui elements in the header
|
// Adjust margin to not overlap with other ui elements in the header
|
||||||
group.Panel.HeaderTextMargin = group.Panel.HeaderTextMargin with { Left = scriptDrag.Right - 12, Right = settingsButton.Width + Utilities.Constants.UIMargin };
|
group.Panel.HeaderTextMargin = group.Panel.HeaderTextMargin with { Left = scriptDrag.Right - 12, Right = settingsButton.Width + Utilities.Constants.UIMargin };
|
||||||
group.Object(values, editor);
|
group.Object(values, editor);
|
||||||
|
|
||||||
// Remove drop down arrows and containment lines if no objects in the group
|
// Remove drop down arrows and containment lines if no objects in the group
|
||||||
if (group.Children.Count == 0)
|
if (group.Children.Count == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
public class SplineEditor : ActorEditor
|
public class SplineEditor : ActorEditor
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Storage undo spline data
|
/// Stores undo spline data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private struct UndoData
|
private struct UndoData
|
||||||
{
|
{
|
||||||
@@ -83,7 +83,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Edit curve options manipulate the curve as free mode
|
/// Edit curve options manipulate the curve as free mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private sealed class FreeTangentMode : EditTangentOptionBase
|
private sealed class FreeTangentMode : EditTangentOptionBase
|
||||||
{
|
{
|
||||||
@@ -98,7 +98,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Edit curve options to set tangents to linear
|
/// Edit curve options to set tangents to linear.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private sealed class LinearTangentMode : EditTangentOptionBase
|
private sealed class LinearTangentMode : EditTangentOptionBase
|
||||||
{
|
{
|
||||||
@@ -107,13 +107,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
{
|
{
|
||||||
SetKeyframeLinear(spline, index);
|
SetKeyframeLinear(spline, index);
|
||||||
|
|
||||||
// change the selection to tangent parent (a spline point / keyframe)
|
// Change the selection to tangent parent (a spline point / keyframe)
|
||||||
Editor.SetSelectSplinePointNode(spline, index);
|
Editor.SetSelectSplinePointNode(spline, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Edit curve options to align tangents of selected spline
|
/// Edit curve options to align tangents of selected spline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private sealed class AlignedTangentMode : EditTangentOptionBase
|
private sealed class AlignedTangentMode : EditTangentOptionBase
|
||||||
{
|
{
|
||||||
@@ -168,8 +168,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Edit curve options manipulate the curve setting selected point
|
/// Edit curve options manipulate the curve setting selected point tangent in as smoothed but tangent out as linear.
|
||||||
/// tangent in as smoothed but tangent out as linear
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private sealed class SmoothInTangentMode : EditTangentOptionBase
|
private sealed class SmoothInTangentMode : EditTangentOptionBase
|
||||||
{
|
{
|
||||||
@@ -182,8 +181,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Edit curve options manipulate the curve setting selected point
|
/// Edit curve options manipulate the curve setting selected point tangent in as linear but tangent out as smoothed.
|
||||||
/// tangent in as linear but tangent out as smoothed
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private sealed class SmoothOutTangentMode : EditTangentOptionBase
|
private sealed class SmoothOutTangentMode : EditTangentOptionBase
|
||||||
{
|
{
|
||||||
@@ -219,7 +217,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
var enabled = EnabledInHierarchy && tab.EnabledInHierarchy;
|
var enabled = EnabledInHierarchy && tab.EnabledInHierarchy;
|
||||||
var style = FlaxEngine.GUI.Style.Current;
|
var style = FlaxEngine.GUI.Style.Current;
|
||||||
var size = Size;
|
var size = Size;
|
||||||
var textHeight = 16.0f;
|
var textHeight = 30.0f;
|
||||||
|
// Make icons smaller when tabs get thinner
|
||||||
var iconSize = size.Y - textHeight;
|
var iconSize = size.Y - textHeight;
|
||||||
var iconRect = new Rectangle((Width - iconSize) / 2, 0, iconSize, iconSize);
|
var iconRect = new Rectangle((Width - iconSize) / 2, 0, iconSize, iconSize);
|
||||||
if (tab._mirrorIcon)
|
if (tab._mirrorIcon)
|
||||||
@@ -230,8 +229,11 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
var color = style.Foreground;
|
var color = style.Foreground;
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
color *= 0.6f;
|
color *= 0.6f;
|
||||||
|
var textRect = new Rectangle(0, size.Y - textHeight, size.X, textHeight);
|
||||||
|
Render2D.PushClip(new Rectangle(Float2.Zero, Size));
|
||||||
Render2D.DrawSprite(tab._customIcon, iconRect, color);
|
Render2D.DrawSprite(tab._customIcon, iconRect, color);
|
||||||
Render2D.DrawText(style.FontMedium, tab._customText, new Rectangle(0, iconSize, size.X, textHeight), color, TextAlignment.Center, TextAlignment.Center);
|
Render2D.DrawText(style.FontMedium, tab._customText, textRect, color, TextAlignment.Center, TextAlignment.Center, TextWrapping.WrapWords, 0.65f);
|
||||||
|
Render2D.PopClip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,18 +293,21 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
return;
|
return;
|
||||||
_selectedSpline = spline;
|
_selectedSpline = spline;
|
||||||
|
|
||||||
layout.Space(10);
|
//var tabSize = 46;
|
||||||
var tabSize = 46;
|
var tabSize = 60;
|
||||||
var icons = Editor.Instance.Icons;
|
var icons = Editor.Instance.Icons;
|
||||||
|
|
||||||
layout.Header("Selected spline point");
|
var group = layout.Group("Selected Point");
|
||||||
_selectedPointsTabs = new Tabs
|
_selectedPointsTabs = new Tabs
|
||||||
{
|
{
|
||||||
Height = tabSize,
|
Height = tabSize,
|
||||||
TabsSize = new Float2(tabSize),
|
TabsSize = new Float2(tabSize),
|
||||||
AutoTabsSize = true,
|
AutoTabsSize = true,
|
||||||
Parent = layout.ContainerControl,
|
Parent = group.ContainerControl,
|
||||||
};
|
};
|
||||||
|
// Move the group above the group containing spline points
|
||||||
|
group.Control.IndexInParent = 3;
|
||||||
|
|
||||||
_linearTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedLinear, "Linear", icons.SplineLinear64));
|
_linearTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedLinear, "Linear", icons.SplineLinear64));
|
||||||
_freeTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedFree, "Free", icons.SplineFree64));
|
_freeTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedFree, "Free", icons.SplineFree64));
|
||||||
_alignedTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedAligned, "Aligned", icons.SplineAligned64));
|
_alignedTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedAligned, "Aligned", icons.SplineAligned64));
|
||||||
@@ -310,13 +315,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
_smoothOutTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedSmoothOut, "Smooth Out", icons.SplineSmoothIn64, true));
|
_smoothOutTangentTab = _selectedPointsTabs.AddTab(new IconTab(OnSetSelectedSmoothOut, "Smooth Out", icons.SplineSmoothIn64, true));
|
||||||
_selectedPointsTabs.SelectedTabIndex = -1;
|
_selectedPointsTabs.SelectedTabIndex = -1;
|
||||||
|
|
||||||
layout.Header("All spline points");
|
group = layout.Group("All Points");
|
||||||
_allPointsTabs = new Tabs
|
_allPointsTabs = new Tabs
|
||||||
{
|
{
|
||||||
Height = tabSize,
|
Height = tabSize,
|
||||||
TabsSize = new Float2(tabSize),
|
TabsSize = new Float2(tabSize),
|
||||||
AutoTabsSize = true,
|
AutoTabsSize = true,
|
||||||
Parent = layout.ContainerControl,
|
Parent = group.ContainerControl,
|
||||||
};
|
};
|
||||||
_setLinearAllTangentsTab = _allPointsTabs.AddTab(new IconTab(OnSetTangentsLinear, "Set Linear Tangents", icons.SplineLinear64));
|
_setLinearAllTangentsTab = _allPointsTabs.AddTab(new IconTab(OnSetTangentsLinear, "Set Linear Tangents", icons.SplineLinear64));
|
||||||
_setSmoothAllTangentsTab = _allPointsTabs.AddTab(new IconTab(OnSetTangentsSmooth, "Set Smooth Tangents", icons.SplineAligned64));
|
_setSmoothAllTangentsTab = _allPointsTabs.AddTab(new IconTab(OnSetTangentsSmooth, "Set Smooth Tangents", icons.SplineAligned64));
|
||||||
|
|||||||
@@ -690,7 +690,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CustomElementsContainer<UniformGridPanel> UniformPanelCapsuleForObjectWithText(LayoutElementsContainer el, string text, ValueContainer values, Color borderColor, out FloatValueBox valueBox)
|
private CustomElementsContainer<UniformGridPanel> UniformPanelCapsuleForObjectWithText(LayoutElementsContainer el, string text, ValueContainer values, Color highlightColor, out FloatValueBox valueBox)
|
||||||
{
|
{
|
||||||
valueBox = null;
|
valueBox = null;
|
||||||
var grid = UniformGridTwoByOne(el);
|
var grid = UniformGridTwoByOne(el);
|
||||||
@@ -701,8 +701,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
{
|
{
|
||||||
valueBox = floatEditorElement.ValueBox;
|
valueBox = floatEditorElement.ValueBox;
|
||||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||||
valueBox.BorderColor = Color.Lerp(borderColor, back, ActorTransformEditor.AxisGreyOutFactor);
|
valueBox.HighlightColor = highlightColor;
|
||||||
valueBox.BorderSelectedColor = borderColor;
|
valueBox.BorderSelectedColor = highlightColor;
|
||||||
}
|
}
|
||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,22 +14,17 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The X axis color.
|
/// The X axis color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Color AxisColorX = new Color(1.0f, 0.0f, 0.02745f, 1.0f);
|
public static Color AxisColorX = new Color(0.8f, 0.0f, 0.027f, 1.0f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Y axis color.
|
/// The Y axis color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Color AxisColorY = new Color(0.239215f, 1.0f, 0.047058f, 1.0f);
|
public static Color AxisColorY = new Color(0.239215f, 0.65f, 0.047058f, 1.0f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Z axis color.
|
/// The Z axis color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static Color AxisColorZ = new Color(0.0f, 0.0235294f, 1.0f, 1.0f);
|
public static Color AxisColorZ = new Color(0.0f, 0.42352f, 0.8f, 1.0f);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The axes colors grey out scale when input field is not focused.
|
|
||||||
/// </summary>
|
|
||||||
public static float AxisGreyOutFactor = 0.6f;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Custom editor for actor position property.
|
/// Custom editor for actor position property.
|
||||||
@@ -43,18 +38,20 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
base.Initialize(layout);
|
base.Initialize(layout);
|
||||||
|
|
||||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||||
|
{
|
||||||
|
ug.SlotPadding = new Margin(3.0f, 0.0f, 0.0f, 0.0f);
|
||||||
CheckLayout(ug);
|
CheckLayout(ug);
|
||||||
|
}
|
||||||
|
|
||||||
// Override colors
|
// Override colors
|
||||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
|
||||||
XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, AxisGreyOutFactor);
|
|
||||||
XElement.ValueBox.BorderSelectedColor = AxisColorX;
|
XElement.ValueBox.BorderSelectedColor = AxisColorX;
|
||||||
XElement.ValueBox.Category = Utils.ValueCategory.Distance;
|
|
||||||
YElement.ValueBox.BorderColor = Color.Lerp(AxisColorY, back, AxisGreyOutFactor);
|
|
||||||
YElement.ValueBox.BorderSelectedColor = AxisColorY;
|
YElement.ValueBox.BorderSelectedColor = AxisColorY;
|
||||||
YElement.ValueBox.Category = Utils.ValueCategory.Distance;
|
|
||||||
ZElement.ValueBox.BorderColor = Color.Lerp(AxisColorZ, back, AxisGreyOutFactor);
|
|
||||||
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
|
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
|
||||||
|
XElement.ValueBox.HighlightColor = AxisColorX;
|
||||||
|
XElement.ValueBox.Category = Utils.ValueCategory.Distance;
|
||||||
|
YElement.ValueBox.HighlightColor = AxisColorY;
|
||||||
|
YElement.ValueBox.Category = Utils.ValueCategory.Distance;
|
||||||
|
ZElement.ValueBox.HighlightColor = AxisColorZ;
|
||||||
ZElement.ValueBox.Category = Utils.ValueCategory.Distance;
|
ZElement.ValueBox.Category = Utils.ValueCategory.Distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,18 +68,20 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
base.Initialize(layout);
|
base.Initialize(layout);
|
||||||
|
|
||||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||||
|
{
|
||||||
|
ug.SlotPadding = new Margin(3.0f, 0.0f, 0.0f, 0.0f);
|
||||||
CheckLayout(ug);
|
CheckLayout(ug);
|
||||||
|
}
|
||||||
|
|
||||||
// Override colors
|
// Override colors
|
||||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
|
||||||
XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, AxisGreyOutFactor);
|
|
||||||
XElement.ValueBox.BorderSelectedColor = AxisColorX;
|
XElement.ValueBox.BorderSelectedColor = AxisColorX;
|
||||||
XElement.ValueBox.Category = Utils.ValueCategory.Angle;
|
|
||||||
YElement.ValueBox.BorderColor = Color.Lerp(AxisColorY, back, AxisGreyOutFactor);
|
|
||||||
YElement.ValueBox.BorderSelectedColor = AxisColorY;
|
YElement.ValueBox.BorderSelectedColor = AxisColorY;
|
||||||
YElement.ValueBox.Category = Utils.ValueCategory.Angle;
|
|
||||||
ZElement.ValueBox.BorderColor = Color.Lerp(AxisColorZ, back, AxisGreyOutFactor);
|
|
||||||
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
|
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
|
||||||
|
XElement.ValueBox.HighlightColor = AxisColorX;
|
||||||
|
XElement.ValueBox.Category = Utils.ValueCategory.Angle;
|
||||||
|
YElement.ValueBox.HighlightColor = AxisColorY;
|
||||||
|
YElement.ValueBox.Category = Utils.ValueCategory.Angle;
|
||||||
|
ZElement.ValueBox.HighlightColor = AxisColorZ;
|
||||||
ZElement.ValueBox.Category = Utils.ValueCategory.Angle;
|
ZElement.ValueBox.Category = Utils.ValueCategory.Angle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,17 +128,19 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||||
|
{
|
||||||
|
ug.SlotPadding = new Margin(3.0f, 0.0f, 0.0f, 0.0f);
|
||||||
CheckLayout(ug);
|
CheckLayout(ug);
|
||||||
|
}
|
||||||
|
|
||||||
// Override colors
|
// Override colors
|
||||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||||
var grayOutFactor = 0.6f;
|
|
||||||
XElement.ValueBox.BorderColor = Color.Lerp(AxisColorX, back, grayOutFactor);
|
|
||||||
XElement.ValueBox.BorderSelectedColor = AxisColorX;
|
XElement.ValueBox.BorderSelectedColor = AxisColorX;
|
||||||
YElement.ValueBox.BorderColor = Color.Lerp(AxisColorY, back, grayOutFactor);
|
|
||||||
YElement.ValueBox.BorderSelectedColor = AxisColorY;
|
YElement.ValueBox.BorderSelectedColor = AxisColorY;
|
||||||
ZElement.ValueBox.BorderColor = Color.Lerp(AxisColorZ, back, grayOutFactor);
|
|
||||||
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
|
ZElement.ValueBox.BorderSelectedColor = AxisColorZ;
|
||||||
|
XElement.ValueBox.HighlightColor = AxisColorX;
|
||||||
|
YElement.ValueBox.HighlightColor = AxisColorY;
|
||||||
|
ZElement.ValueBox.HighlightColor = AxisColorZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
SetValue(Editor.Instance.ContentDatabase.Find(Utilities.Utils.ToPathAbsolute(path)));
|
SetValue(Editor.Instance.ContentDatabase.Find(Utilities.Utils.ToPathAbsolute(path)));
|
||||||
else if (value is Asset)
|
else if (value is Asset)
|
||||||
SetValue(FlaxEngine.Content.LoadAsync(path));
|
SetValue(FlaxEngine.Content.LoadAsync(path));
|
||||||
else if (value is string)
|
else if (value is string || Values.Type == typeof(string))
|
||||||
SetValue(path);
|
SetValue(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user