Compare commits
515 Commits
work
...
d0cc2b67a7
| Author | SHA1 | Date | |
|---|---|---|---|
| d0cc2b67a7 | |||
| 9b93bef983 | |||
| ee95a292a6 | |||
| a336b4966f | |||
| da1c112c92 | |||
| 9ffe206b81 | |||
| a87a6898ae | |||
| ebf57ef9b0 | |||
| 668a4dbb4d | |||
|
|
e19be4c0c6 | ||
|
|
2d5fdfef2f | ||
|
|
46ee6bc193 | ||
|
|
a2ee2ec6ac | ||
|
|
2caaef02ad | ||
|
|
b62f331b08 | ||
|
|
f7b306532b | ||
|
|
212abe7d90 | ||
|
|
7dfc37f652 | ||
|
|
12decc3320 | ||
|
|
d7a528cdbc | ||
|
|
18364d2a8b | ||
|
|
5a9eedfadb | ||
|
|
be7871c292 | ||
|
|
abdeaa9354 | ||
|
|
d3389604b0 | ||
|
|
d426c5b0d9 | ||
|
|
8da0d2c4ce | ||
|
|
20f576783b | ||
|
|
2bf62cc54f | ||
|
|
ef2c551cee | ||
|
|
65cf59642c | ||
|
|
e2fc8a6283 | ||
|
|
73976f3ed9 | ||
|
|
7ab6bafe39 | ||
|
|
deb2ad7c8f | ||
|
|
cd7fc3242e | ||
|
|
31a0a77e7c | ||
|
|
f0ec4a901a | ||
|
|
8cb67f017a | ||
|
|
7b643e9685 | ||
|
|
39803ce6b2 | ||
|
|
2f1f380062 | ||
|
|
f8dbf363b6 | ||
|
|
fc1451254d | ||
|
|
d3c54e590a | ||
|
|
361fc3ecfb | ||
|
|
3682159da6 | ||
|
|
e9f83f77bb | ||
|
|
823ed247d2 | ||
|
|
8f3b80492e | ||
|
|
c61c013517 | ||
|
|
a2170ffd8a | ||
|
|
4f1f77fb32 | ||
|
|
6ae370f8fc | ||
|
|
da5c8555e5 | ||
|
|
c4c7ee941f | ||
|
|
4f45b3c1d0 | ||
|
|
4c640b915f | ||
|
|
1f3f1ea67e | ||
|
|
60c19303f6 | ||
|
|
adcfc50218 | ||
|
|
9b812ec34a | ||
|
|
7e1ac5e167 | ||
|
|
028b5fedec | ||
|
|
9cc2c1da40 | ||
|
|
93219793d5 | ||
|
|
32f2ef3f06 | ||
|
|
5ed8564293 | ||
|
|
7c87ade12b | ||
|
|
7f87678282 | ||
|
|
e429d29d17 | ||
|
|
086a49f45d | ||
|
|
c46e1164d6 | ||
|
|
2a5898c1de | ||
|
|
f09d6aa0eb | ||
|
|
0848f1fa83 | ||
|
|
537d8b57ca | ||
|
|
02c5ad3fa4 | ||
|
|
41e851298d | ||
|
|
4a3fb41035 | ||
|
|
d57eec3403 | ||
|
|
87e2c4c4d5 | ||
|
|
797cb3c3f2 | ||
|
|
47670251ef | ||
|
|
cf1ef91246 | ||
|
|
7060cb5696 | ||
|
|
c449833d35 | ||
|
|
284aeca51a | ||
|
|
d8f7199c11 | ||
|
|
dc05bbbbcd | ||
|
|
3fcc9ed01f | ||
|
|
70ba750a5e | ||
|
|
50271199ac | ||
|
|
d1a99c9396 | ||
|
|
4ae3d57adc | ||
|
|
99b9967806 | ||
|
|
2f7e84253a | ||
|
|
2f55cb938f | ||
|
|
a86661a855 | ||
|
|
a68ce6633a | ||
|
|
5d57afe3aa | ||
|
|
6705138247 | ||
|
|
276caf771c | ||
|
|
5eea5a72c9 | ||
|
|
e9a7b1c8eb | ||
|
|
a151c78412 | ||
|
|
5f1e905e8f | ||
|
|
a0f764a774 | ||
|
|
7da5ce3ed4 | ||
|
|
1186833b2d | ||
|
|
bb180b0f59 | ||
|
|
5d1c79929a | ||
|
|
3f5a4cc4c9 | ||
|
|
62fd8ac967 | ||
|
|
d904b92f2e | ||
|
|
87e2b76ffa | ||
|
|
c5e11aed15 | ||
|
|
85d61b334b | ||
|
|
26e94f6f8e | ||
|
|
902744a0ce | ||
|
|
1c581bceaf | ||
|
|
9cc44825c6 | ||
|
|
92f4327fc2 | ||
|
|
47711ec5be | ||
|
|
d1fbc66cb9 | ||
|
|
7183a3306e | ||
|
|
fd191f7ffb | ||
|
|
2604d58687 | ||
|
|
01d1d634c2 | ||
|
|
c7e403661d | ||
|
|
1196db6d17 | ||
|
|
553a007508 | ||
|
|
de2ee36529 | ||
|
|
eea44ac897 | ||
|
|
c124713e99 | ||
|
|
364a523375 | ||
|
|
afdd264e63 | ||
|
|
8ec54f7b1c | ||
|
|
521518bde4 | ||
|
|
56077a268a | ||
|
|
a0ca000793 | ||
|
|
ae4ae7a638 | ||
|
|
e2a4c8ab03 | ||
|
|
7a40722964 | ||
|
|
1de8909d05 | ||
|
|
9749487e24 | ||
|
|
55968a8ddc | ||
|
|
e325b190ea | ||
|
|
ada6b9140f | ||
|
|
5582579173 | ||
|
|
88773e71e5 | ||
|
|
9e1f488f22 | ||
|
|
a471861e92 | ||
|
|
3d182c89f3 | ||
|
|
e3810a9938 | ||
|
|
f323fdb592 | ||
| f0dea9d528 | |||
|
|
b537a80031 | ||
|
|
5e52bf6469 | ||
|
|
8482f93a0f | ||
|
|
64c62f269c | ||
|
|
19d0d3b683 | ||
|
|
1f56c75821 | ||
|
|
64e127a47a | ||
|
|
8921cf5156 | ||
|
|
24e088fc08 | ||
|
|
14a69a11df | ||
| 1d8f221f1b | |||
| d70a003617 | |||
| b443b74d18 | |||
|
|
42b542d190 | ||
|
|
576b0710e0 | ||
|
|
44e70692a2 | ||
|
|
857b0c5ac3 | ||
|
|
1f6d837117 | ||
|
|
67220d3f80 | ||
|
|
c5d06b2c8b | ||
|
|
3b19e1b40c | ||
|
|
831fb0f442 | ||
|
|
cd22cd059d | ||
|
|
3e363c8275 | ||
|
|
c44d939c08 | ||
|
|
c0c9df49dc | ||
|
|
80de56f469 | ||
|
|
f1ecbf828e | ||
|
|
f1c4fd464a | ||
|
|
212b0de29b | ||
|
|
5a2555f845 | ||
|
|
c57e128ff1 | ||
|
|
eff5f84185 | ||
|
|
ad1163bccc | ||
|
|
1042ad4e7d | ||
|
|
8fdda1a71a | ||
|
|
3f7fe635d8 | ||
|
|
fcebc57ed0 | ||
|
|
c40e447bb7 | ||
|
|
e6f94bb154 | ||
|
|
adbc546978 | ||
|
|
2d171967e9 | ||
|
|
33a0e6ac7d | ||
|
|
848cc38bf1 | ||
|
|
91cd1e8065 | ||
|
|
9fafb47abb | ||
|
|
5222f1d35c | ||
|
|
785649f9d5 | ||
|
|
d47ac95681 | ||
|
|
703e0cb7ca | ||
|
|
ef7c7f2d30 | ||
|
|
f3d375e356 | ||
|
|
a3073321cf | ||
|
|
824b49dd88 | ||
|
|
d0e7bff03a | ||
|
|
d314d5b324 | ||
|
|
a027ed3b63 | ||
|
|
bcedb05a2c | ||
|
|
b36be95947 | ||
|
|
826009c1b4 | ||
|
|
4ca399af71 | ||
|
|
c1f022520d | ||
|
|
2efd20f223 | ||
|
|
00dd432fbc | ||
|
|
f707508d70 | ||
|
|
b965ca6c8c | ||
|
|
26f4bcbc25 | ||
|
|
6fea9eefaa | ||
|
|
47caa6af28 | ||
|
|
9aedb37ac2 | ||
|
|
e4bc2c69c7 | ||
|
|
6db9265112 | ||
|
|
21a84c5b84 | ||
|
|
633b5857c9 | ||
|
|
9f9dac1543 | ||
|
|
df6f8fd8ae | ||
|
|
4bd8ce37ac | ||
|
|
40e204839f | ||
|
|
d6c75b3f86 | ||
|
|
687c283533 | ||
|
|
70ee8501a5 | ||
|
|
2c34bd2308 | ||
| fc341a86e7 | |||
|
|
5023e3277b | ||
|
|
9003d855b3 | ||
|
|
75906719d4 | ||
|
|
9a59925a36 | ||
|
|
d5ca80c2c1 | ||
|
|
cb07ee77aa | ||
|
|
680783f2b0 | ||
|
|
4a28b4bd6c | ||
|
|
4bf36f3467 | ||
|
|
2c1713d300 | ||
|
|
8136691914 | ||
|
|
da23e287c0 | ||
|
|
e0825d870d | ||
|
|
86dbe6b93d | ||
|
|
e71b74c625 | ||
|
|
45f6ef29e9 | ||
|
|
0fabca19cd | ||
|
|
0bc242c738 | ||
|
|
8c548ceff2 | ||
|
|
46fda05000 | ||
|
|
1fee95be1c | ||
|
|
8c66ae99a3 | ||
|
|
1cf98e2188 | ||
|
|
6a8553a277 | ||
|
|
a02b7d4a1a | ||
|
|
606dfa4e2e | ||
|
|
b6f853a01c | ||
|
|
fc2112ec93 | ||
|
|
6ccfbfeff1 | ||
|
|
f21accd466 | ||
|
|
38b4ace1a8 | ||
|
|
774b6bd72c | ||
|
|
9c4606fefc | ||
|
|
0e50e47cce | ||
|
|
285fa870d0 | ||
|
|
69ed0bf56f | ||
|
|
237b9bccd5 | ||
|
|
f5fd7319e1 | ||
|
|
e04c0c4ace | ||
|
|
f6d0b073da | ||
|
|
68a7cf4f18 | ||
|
|
a91360529f | ||
|
|
bf9ca14deb | ||
|
|
cb92a2b8cb | ||
|
|
8a73d79936 | ||
|
|
2f7d7a0f2a | ||
|
|
d43c0c593f | ||
|
|
1087bd2445 | ||
|
|
5e19a9729b | ||
|
|
69e12d77be | ||
|
|
cdb09847ec | ||
|
|
169d3e964d | ||
|
|
cf503cf921 | ||
|
|
6fd4ef735e | ||
|
|
303087c4c4 | ||
| 68da28ffe8 | |||
|
|
427e76e76e | ||
| b183b5bcfc | |||
|
|
278dead0bd | ||
|
|
cdff7708fb | ||
|
|
b4d501cd6a | ||
|
|
9cf9fae453 | ||
|
|
7fcf6f9c97 | ||
|
|
1bedfd3adf | ||
|
|
80d19a002f | ||
|
|
99707b6586 | ||
|
|
9f14bb7279 | ||
|
|
a18314c669 | ||
|
|
c946fa239e | ||
|
|
d109e5ca9f | ||
|
|
bc0e1f81e7 | ||
|
|
c1c806490f | ||
|
|
4fd6343fb9 | ||
|
|
a2e9d8d77b | ||
|
|
ff3d785483 | ||
|
|
82231981dc | ||
|
|
1915e1e7f4 | ||
|
|
b5a431d2f5 | ||
|
|
3907bc4957 | ||
|
|
854f3acd4c | ||
|
|
519a9c0a14 | ||
|
|
0ea555b041 | ||
|
|
90d1e63b58 | ||
|
|
0369d9b2cb | ||
|
|
9fabc1028a | ||
|
|
2a9260ddd5 | ||
|
|
3d84380175 | ||
|
|
545df6ce35 | ||
|
|
d4355e31d8 | ||
|
|
3ffb067e55 | ||
|
|
959371a995 | ||
|
|
cf9c203855 | ||
|
|
a5838f739d | ||
|
|
b1710c4d01 | ||
|
|
baf0cfce8e | ||
|
|
a1a6d4738f | ||
|
|
761ea094d6 | ||
|
|
8e043e533e | ||
|
|
1a88fefd76 | ||
|
|
abe496fe12 | ||
|
|
c9e0637b0f | ||
|
|
db660721ce | ||
|
|
2730d63257 | ||
|
|
31764d6d4e | ||
|
|
34ba45cd5a | ||
|
|
5de5d8f683 | ||
|
|
744c94b3cc | ||
|
|
e27880c1e6 | ||
|
|
b26d6ea108 | ||
|
|
5c5341e346 | ||
|
|
6f15ef7690 | ||
|
|
0e3a22faa0 | ||
|
|
0dc1e04c89 | ||
|
|
5c7712daad | ||
|
|
0f81c64964 | ||
|
|
7603109dce | ||
|
|
01617ae684 | ||
|
|
4aa2676084 | ||
|
|
a8b9211c32 | ||
|
|
9c5060584d | ||
|
|
846a0b5685 | ||
|
|
08154d8fe5 | ||
|
|
a53a438c3c | ||
|
|
bb8f569c41 | ||
|
|
6307ad7979 | ||
|
|
b6229350a3 | ||
|
|
5dc4ebade1 | ||
|
|
3cd5890db1 | ||
|
|
522d8d89e6 | ||
|
|
492a5f979d | ||
|
|
5e4d564338 | ||
|
|
8fcbef863e | ||
|
|
c68b75a298 | ||
|
|
8f63a99a2c | ||
|
|
6d05bf16b1 | ||
|
|
b8218e9ab4 | ||
|
|
99323c1d2f | ||
|
|
17c0892ff1 | ||
|
|
ad6764e6d7 | ||
|
|
0bfd38e065 | ||
|
|
a00ffe6ec3 | ||
|
|
a7ffd9e57f | ||
|
|
354eaac56c | ||
|
|
8c51ea511a | ||
|
|
2af266727f | ||
|
|
f37b75df7b | ||
|
|
6132e45e25 | ||
|
|
753035c452 | ||
|
|
acc1777638 | ||
|
|
69585618ed | ||
|
|
af0ea65d78 | ||
|
|
751d179cdb | ||
|
|
2dc44ac1a6 | ||
|
|
2550b9f88e | ||
|
|
c3cf8fba98 | ||
|
|
6f172f8f2c | ||
|
|
735d611de1 | ||
|
|
d6a33d5a1c | ||
|
|
6cbd40e6d8 | ||
|
|
8ac2385447 | ||
|
|
b8e00f2ed1 | ||
|
|
b6e18ccae5 | ||
|
|
1fb6586dff | ||
|
|
e6265105b5 | ||
|
|
892e2e0d1e | ||
|
|
90551b32bc | ||
|
|
cd08eeaf95 | ||
|
|
f8dadac453 | ||
|
|
f87e2c2229 | ||
|
|
18035a8604 | ||
|
|
fc46219a82 | ||
|
|
2546e19d65 | ||
|
|
6763436eff | ||
|
|
2754d61c05 | ||
|
|
7fd278a689 | ||
|
|
2d2c5411cd | ||
|
|
3e0c085bf3 | ||
|
|
c882b547c8 | ||
|
|
9646dd3fc2 | ||
|
|
c0cce748cc | ||
|
|
ab8612a914 | ||
|
|
20f1e67700 | ||
|
|
eda7f7e90f | ||
|
|
a22b33d3bb | ||
|
|
8ed2d6da56 | ||
|
|
bb37f980ed | ||
|
|
349547f66c | ||
|
|
a1e4ed05c4 | ||
|
|
10e9aee8ce | ||
|
|
4af26a5516 | ||
|
|
3e82e550f3 | ||
|
|
33b540ed9e | ||
|
|
50871d8885 | ||
|
|
c27a9808c4 | ||
|
|
bdaf31b54f | ||
|
|
3abbf08f1f | ||
|
|
a8eb4fc140 | ||
|
|
83374164db | ||
|
|
c5bfc6bc3d | ||
|
|
d698bf96cc | ||
|
|
b3f88e156c | ||
|
|
7418d60f24 | ||
|
|
3981d5090c | ||
| a93a940630 | |||
| 3e353db1fa | |||
|
|
75647d149a | ||
|
|
52b64540ab | ||
|
|
d7ab497b0e | ||
|
|
683a48a6e3 | ||
|
|
a41fc51f92 | ||
|
|
b9cfd054c1 | ||
|
|
53d4ea51af | ||
|
|
c8622d1801 | ||
|
|
fdd22c3380 | ||
|
|
53761df85e | ||
|
|
ecaae2b458 | ||
|
|
a4d3ede368 | ||
|
|
92edb996f2 | ||
|
|
2e0c35e6e4 | ||
|
|
baba151d8a | ||
|
|
b44d4107c0 | ||
|
|
f40c67ddf0 | ||
|
|
ec154b4998 | ||
|
|
28eaac37dc | ||
|
|
6997cbeb47 | ||
|
|
6b78b498f7 | ||
|
|
c4130aa20f | ||
|
|
71991ff8c7 | ||
|
|
c9fe9213b3 | ||
|
|
608839b6a5 | ||
|
|
954cf3eb5b | ||
|
|
245d7de818 | ||
|
|
49e0cc937e | ||
|
|
f71bdd0962 | ||
|
|
47a6da9e40 | ||
|
|
1704cfba4d | ||
|
|
40dae18b76 | ||
|
|
4e44831bbe | ||
|
|
0c1e0e48d4 | ||
|
|
6884df02fd | ||
|
|
63655d18c5 | ||
|
|
4170699348 | ||
|
|
d58a9beb3d | ||
|
|
5049f3b2d8 | ||
|
|
6e44eebb9e | ||
|
|
aecbab5613 | ||
|
|
6bf90f29c5 | ||
|
|
19edce1770 | ||
|
|
e17b96b2d6 | ||
|
|
9b6feb9367 | ||
| fc96b248cb | |||
| 36c1909111 | |||
| 643fe639e5 | |||
| 78dffc9ad1 | |||
|
|
1dfd717093 | ||
|
|
68ef6f08c6 | ||
|
|
a0b80c6096 | ||
|
|
59ac8a3f60 | ||
|
|
dd281bbca8 | ||
|
|
2e48be97b6 | ||
|
|
0b7550e5ca | ||
|
|
391c67b1a9 | ||
|
|
975cc79085 | ||
|
|
468babae87 | ||
|
|
051d363358 | ||
|
|
9b495bbc68 | ||
|
|
516d4263c9 | ||
|
|
ba35123420 | ||
|
|
409703d675 | ||
|
|
570c3f7462 | ||
|
|
42d02a9e63 | ||
|
|
819c93f6fb | ||
|
|
0c645cbc78 | ||
|
|
e665cc7500 | ||
|
|
0a516ac98d |
42
.github/ISSUE_TEMPLATE/1-bug.yaml
vendored
Normal file
42
.github/ISSUE_TEMPLATE/1-bug.yaml
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: File a bug report.
|
||||||
|
title: "[Bug]: "
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report! Please attach any minimal reproduction projects!
|
||||||
|
- type: textarea
|
||||||
|
id: description-area
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: Please provide a description of the bug and what you expected to happen.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: steps-area
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: Please provide reproduction steps if possible.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: Version
|
||||||
|
description: What version of Flax are you running?
|
||||||
|
options:
|
||||||
|
- '1.8'
|
||||||
|
- '1.9'
|
||||||
|
- '1.10'
|
||||||
|
- '1.11'
|
||||||
|
- master branch
|
||||||
|
default: 2
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: logs
|
||||||
|
attributes:
|
||||||
|
label: Relevant logs
|
||||||
|
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||||
|
render: shell
|
||||||
22
.github/ISSUE_TEMPLATE/2-feature-request.yaml
vendored
Normal file
22
.github/ISSUE_TEMPLATE/2-feature-request.yaml
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Feature Request
|
||||||
|
description: File a feature request.
|
||||||
|
title: "[Request]: "
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out a feature request!
|
||||||
|
- type: textarea
|
||||||
|
id: description-area
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: Please provide a description of the feature!
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: benefits-area
|
||||||
|
attributes:
|
||||||
|
label: Benefits
|
||||||
|
description: Please provide what benefits this feature would provide to the engine!
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialAxisLocked.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/MaterialAxisLocked.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/IconsAtlas.flax
(Stored with Git LFS)
BIN
Content/Editor/IconsAtlas.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
@@ -6,6 +6,7 @@
|
|||||||
@3
|
@3
|
||||||
|
|
||||||
#include "./Flax/Common.hlsl"
|
#include "./Flax/Common.hlsl"
|
||||||
|
#include "./Flax/Stencil.hlsl"
|
||||||
#include "./Flax/MaterialCommon.hlsl"
|
#include "./Flax/MaterialCommon.hlsl"
|
||||||
#include "./Flax/GBufferCommon.hlsl"
|
#include "./Flax/GBufferCommon.hlsl"
|
||||||
@7
|
@7
|
||||||
@@ -13,11 +14,14 @@
|
|||||||
META_CB_BEGIN(0, Data)
|
META_CB_BEGIN(0, Data)
|
||||||
float4x4 WorldMatrix;
|
float4x4 WorldMatrix;
|
||||||
float4x4 InvWorld;
|
float4x4 InvWorld;
|
||||||
float4x4 SVPositionToWorld;
|
float4x4 SvPositionToWorld;
|
||||||
|
float3 Padding0;
|
||||||
|
uint RenderLayersMask;
|
||||||
@1META_CB_END
|
@1META_CB_END
|
||||||
|
|
||||||
// Use depth buffer for per-pixel decal layering
|
// Use depth buffer for per-pixel decal layering
|
||||||
Texture2D DepthBuffer : register(t0);
|
Texture2D DepthBuffer : register(t0);
|
||||||
|
Texture2D<uint2> StencilBuffer : register(t1);
|
||||||
|
|
||||||
// Material shader resources
|
// Material shader resources
|
||||||
@2
|
@2
|
||||||
@@ -27,12 +31,63 @@ struct MaterialInput
|
|||||||
float3 WorldPosition;
|
float3 WorldPosition;
|
||||||
float TwoSidedSign;
|
float TwoSidedSign;
|
||||||
float2 TexCoord;
|
float2 TexCoord;
|
||||||
|
float4 TexCoord_DDX_DDY;
|
||||||
float3x3 TBN;
|
float3x3 TBN;
|
||||||
float4 SvPosition;
|
float4 SvPosition;
|
||||||
float3 PreSkinnedPosition;
|
float3 PreSkinnedPosition;
|
||||||
float3 PreSkinnedNormal;
|
float3 PreSkinnedNormal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Calculates decal texcoords for a given pixel position (sampels depth buffer and projects value to decal space).
|
||||||
|
float2 SvPositionToDecalUV(float4 svPosition)
|
||||||
|
{
|
||||||
|
float2 screenUV = svPosition.xy * ScreenSize.zw;
|
||||||
|
svPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;
|
||||||
|
float4 positionHS = mul(float4(svPosition.xyz, 1), SvPositionToWorld);
|
||||||
|
float3 positionWS = positionHS.xyz / positionHS.w;
|
||||||
|
float3 positionOS = mul(float4(positionWS, 1), InvWorld).xyz;
|
||||||
|
return positionOS.xz + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manually compute ddx/ddy for decal texture cooordinates to avoid the 2x2 pixels artifacts on the edges of geometry under decal
|
||||||
|
// [Reference: https://www.humus.name/index.php?page=3D&ID=84]
|
||||||
|
float4 CalculateTextureDerivatives(float4 svPosition, float2 texCoord)
|
||||||
|
{
|
||||||
|
float4 svDiffX = float4(1, 0, 0, 0);
|
||||||
|
float2 uvDiffX0 = texCoord - SvPositionToDecalUV(svPosition - svDiffX);
|
||||||
|
float2 uvDiffX1 = SvPositionToDecalUV(svPosition + svDiffX) - texCoord;
|
||||||
|
float2 dx = dot(uvDiffX0, uvDiffX0) < dot(uvDiffX1, uvDiffX1) ? uvDiffX0 : uvDiffX1;
|
||||||
|
|
||||||
|
float4 svDiffY = float4(0, 1, 0, 0);
|
||||||
|
float2 uvDiffY0 = texCoord - SvPositionToDecalUV(svPosition - svDiffY);
|
||||||
|
float2 uvDiffY1 = SvPositionToDecalUV(svPosition + svDiffY) - texCoord;
|
||||||
|
float2 dy = dot(uvDiffY0, uvDiffY0) < dot(uvDiffY1, uvDiffY1) ? uvDiffY0 : uvDiffY1;
|
||||||
|
|
||||||
|
return float4(dx, dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Computes the mipmap level for a specific texture dimensions to be sampled at decal texture cooordinates.
|
||||||
|
// [Reference: https://hugi.scene.org/online/coding/hugi%2014%20-%20comipmap.htm]
|
||||||
|
float CalculateTextureMipmap(MaterialInput input, float2 textureSize)
|
||||||
|
{
|
||||||
|
float2 dx = input.TexCoord_DDX_DDY.xy * textureSize;
|
||||||
|
float2 dy = input.TexCoord_DDX_DDY.zw * textureSize;
|
||||||
|
float d = max(dot(dx, dx), dot(dy, dy));
|
||||||
|
return (0.5 * 0.5) * log2(d); // Hardcoded half-mip rate reduction to avoid artifacts when decal is moved over dither texture
|
||||||
|
}
|
||||||
|
float CalculateTextureMipmap(MaterialInput input, Texture2D t)
|
||||||
|
{
|
||||||
|
float2 textureSize;
|
||||||
|
t.GetDimensions(textureSize.x, textureSize.y);
|
||||||
|
return CalculateTextureMipmap(input, textureSize);
|
||||||
|
}
|
||||||
|
float CalculateTextureMipmap(MaterialInput input, TextureCube t)
|
||||||
|
{
|
||||||
|
float2 textureSize;
|
||||||
|
t.GetDimensions(textureSize.x, textureSize.y);
|
||||||
|
return CalculateTextureMipmap(input, textureSize);
|
||||||
|
}
|
||||||
|
|
||||||
// Transforms a vector from tangent space to world space
|
// Transforms a vector from tangent space to world space
|
||||||
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
|
float3 TransformTangentVectorToWorld(MaterialInput input, float3 tangentVector)
|
||||||
{
|
{
|
||||||
@@ -116,7 +171,6 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Input macro specified by the material: DECAL_BLEND_MODE
|
// Input macro specified by the material: DECAL_BLEND_MODE
|
||||||
|
|
||||||
#define DECAL_BLEND_MODE_TRANSLUCENT 0
|
#define DECAL_BLEND_MODE_TRANSLUCENT 0
|
||||||
#define DECAL_BLEND_MODE_STAIN 1
|
#define DECAL_BLEND_MODE_STAIN 1
|
||||||
#define DECAL_BLEND_MODE_NORMAL 2
|
#define DECAL_BLEND_MODE_NORMAL 2
|
||||||
@@ -150,10 +204,18 @@ void PS_Decal(
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Stencil masking
|
||||||
|
uint stencilObjectLayer = STENCIL_BUFFER_OBJECT_LAYER(STENCIL_BUFFER_LOAD(StencilBuffer, SvPosition.xy));
|
||||||
|
if ((RenderLayersMask & (1 << stencilObjectLayer)) == 0)
|
||||||
|
{
|
||||||
|
clip(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float2 screenUV = SvPosition.xy * ScreenSize.zw;
|
float2 screenUV = SvPosition.xy * ScreenSize.zw;
|
||||||
SvPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;
|
SvPosition.z = SAMPLE_RT(DepthBuffer, screenUV).r;
|
||||||
|
|
||||||
float4 positionHS = mul(float4(SvPosition.xyz, 1), SVPositionToWorld);
|
float4 positionHS = mul(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 = mul(float4(positionWS, 1), InvWorld).xyz;
|
||||||
|
|
||||||
@@ -166,8 +228,9 @@ void PS_Decal(
|
|||||||
materialInput.TexCoord = decalUVs;
|
materialInput.TexCoord = decalUVs;
|
||||||
materialInput.TwoSidedSign = 1;
|
materialInput.TwoSidedSign = 1;
|
||||||
materialInput.SvPosition = SvPosition;
|
materialInput.SvPosition = SvPosition;
|
||||||
|
materialInput.TexCoord_DDX_DDY = CalculateTextureDerivatives(materialInput.SvPosition, materialInput.TexCoord);
|
||||||
// Build tangent to world transformation matrix
|
|
||||||
|
// Calculate tangent-space
|
||||||
float3 ddxWp = ddx(positionWS);
|
float3 ddxWp = ddx(positionWS);
|
||||||
float3 ddyWp = ddy(positionWS);
|
float3 ddyWp = ddy(positionWS);
|
||||||
materialInput.TBN[0] = normalize(ddyWp);
|
materialInput.TBN[0] = normalize(ddyWp);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ TextureCube EnvProbe : register(t__SRV__);
|
|||||||
TextureCube SkyLightTexture : register(t__SRV__);
|
TextureCube SkyLightTexture : register(t__SRV__);
|
||||||
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
||||||
Texture2D<float> ShadowMap : register(t__SRV__);
|
Texture2D<float> ShadowMap : register(t__SRV__);
|
||||||
|
Texture3D VolumetricFogTexture : register(t__SRV__);
|
||||||
@4// Forward Shading: Utilities
|
@4// Forward Shading: Utilities
|
||||||
// Public accessors for lighting data, use them as data binding might change but those methods will remain.
|
// Public accessors for lighting data, use them as data binding might change but those methods will remain.
|
||||||
LightData GetDirectionalLight() { return DirectionalLight; }
|
LightData GetDirectionalLight() { return DirectionalLight; }
|
||||||
@@ -151,7 +152,25 @@ void PS_Forward(
|
|||||||
|
|
||||||
#if USE_FOG && MATERIAL_SHADING_MODEL != SHADING_MODEL_UNLIT
|
#if USE_FOG && MATERIAL_SHADING_MODEL != SHADING_MODEL_UNLIT
|
||||||
// Calculate exponential height fog
|
// Calculate exponential height fog
|
||||||
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0, gBuffer.ViewPos.z);
|
#if DIRECTX && FEATURE_LEVEL < FEATURE_LEVEL_SM6
|
||||||
|
// TODO: fix D3D11/D3D10 bug with incorrect distance
|
||||||
|
float fogSceneDistance = distance(materialInput.WorldPosition, ViewPos);
|
||||||
|
#else
|
||||||
|
float fogSceneDistance = gBuffer.ViewPos.z;
|
||||||
|
#endif
|
||||||
|
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0, fogSceneDistance);
|
||||||
|
|
||||||
|
if (ExponentialHeightFog.VolumetricFogMaxDistance > 0)
|
||||||
|
{
|
||||||
|
// Sample volumetric fog and mix it in
|
||||||
|
float2 screenUV = materialInput.SvPosition.xy * ScreenSize.zw;
|
||||||
|
float3 viewVector = materialInput.WorldPosition - ViewPos;
|
||||||
|
float sceneDepth = length(viewVector);
|
||||||
|
float depthSlice = sceneDepth / ExponentialHeightFog.VolumetricFogMaxDistance;
|
||||||
|
float3 volumeUV = float3(screenUV, depthSlice);
|
||||||
|
float4 volumetricFog = VolumetricFogTexture.SampleLevel(SamplerLinearClamp, volumeUV, 0);
|
||||||
|
fog = CombineVolumetricFog(fog, volumetricFog);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply fog to the output color
|
// Apply fog to the output color
|
||||||
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
|
#if MATERIAL_BLEND == MATERIAL_BLEND_OPAQUE
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ float TimeParam;
|
|||||||
float4 ViewInfo;
|
float4 ViewInfo;
|
||||||
float4 ScreenSize;
|
float4 ScreenSize;
|
||||||
float4 ViewSize;
|
float4 ViewSize;
|
||||||
|
float3 ViewPadding0;
|
||||||
|
float ScaledTimeParam;
|
||||||
@1META_CB_END
|
@1META_CB_END
|
||||||
|
|
||||||
// Shader resources
|
// Shader resources
|
||||||
|
|||||||
@@ -645,7 +645,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
|
|||||||
materialInput.TBN = output.TBN;
|
materialInput.TBN = output.TBN;
|
||||||
materialInput.TwoSidedSign = 1;
|
materialInput.TwoSidedSign = 1;
|
||||||
materialInput.SvPosition = output.Position;
|
materialInput.SvPosition = output.Position;
|
||||||
materialInput.PreSkinnedPosition = Position;
|
materialInput.PreSkinnedPosition = position;
|
||||||
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
|
materialInput.PreSkinnedNormal = tangentToLocal[2].xyz;
|
||||||
materialInput.InstanceOrigin = output.InstanceOrigin;
|
materialInput.InstanceOrigin = output.InstanceOrigin;
|
||||||
materialInput.InstanceParams = output.InstanceParams;
|
materialInput.InstanceParams = output.InstanceParams;
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ float4 ViewInfo;
|
|||||||
float4 ScreenSize;
|
float4 ScreenSize;
|
||||||
float4 TemporalAAJitter;
|
float4 TemporalAAJitter;
|
||||||
float4x4 InverseViewProjectionMatrix;
|
float4x4 InverseViewProjectionMatrix;
|
||||||
|
float3 ViewPadding0;
|
||||||
|
float ScaledTimeParam;
|
||||||
@1META_CB_END
|
@1META_CB_END
|
||||||
|
|
||||||
// Shader resources
|
// Shader resources
|
||||||
|
|||||||
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultRadialMenu.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultRadialMenu.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/Textures/PreIntegratedGF.flax
(Stored with Git LFS)
BIN
Content/Engine/Textures/PreIntegratedGF.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/BitonicSort.flax
(Stored with Git LFS)
BIN
Content/Shaders/BitonicSort.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Fog.flax
(Stored with Git LFS)
BIN
Content/Shaders/Fog.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GPUParticlesSorting.flax
(Stored with Git LFS)
BIN
Content/Shaders/GPUParticlesSorting.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/PostProcessing.flax
(Stored with Git LFS)
BIN
Content/Shaders/PostProcessing.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Reflections.flax
(Stored with Git LFS)
BIN
Content/Shaders/Reflections.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/SSAO.flax
(Stored with Git LFS)
BIN
Content/Shaders/SSAO.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/SSR.flax
(Stored with Git LFS)
BIN
Content/Shaders/SSR.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Sky.flax
(Stored with Git LFS)
BIN
Content/Shaders/Sky.flax
(Stored with Git LFS)
Binary file not shown.
@@ -4,7 +4,7 @@
|
|||||||
"Major": 1,
|
"Major": 1,
|
||||||
"Minor": 11,
|
"Minor": 11,
|
||||||
"Revision": 0,
|
"Revision": 0,
|
||||||
"Build": 6800
|
"Build": 6801
|
||||||
},
|
},
|
||||||
"Company": "Flax",
|
"Company": "Flax",
|
||||||
"Copyright": "Copyright (c) 2012-2025 Wojciech Figat. All rights reserved.",
|
"Copyright": "Copyright (c) 2012-2025 Wojciech Figat. All rights reserved.",
|
||||||
|
|||||||
@@ -73,6 +73,24 @@
|
|||||||
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=TYPEDEF/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=TYPEDEF/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION_005FMEMBER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION_005FMEMBER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Abbreviations/=CCD/@EntryIndexedValue">CCD</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Abbreviations/=GPU/@EntryIndexedValue">GPU</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=175CE9C669E52F4D92FD2C07848740BD/@EntryIndexedValue"><NamingElement Priority="11" Title="Class and struct public fields"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="PUBLIC"><type Name="class field" /><type Name="struct field" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=32EB6D69783B3E4481A733193E338089/@EntryIndexedValue"><NamingElement Priority="9" Title="Class and struct methods"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="member function" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=3C4E0D59F298854F9608A9B454E8FF5E/@EntryIndexedValue"><NamingElement Priority="17" Title="Typedefs"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="type alias" /><type Name="typedef" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=499C9026DADA2B448BCD0B2C54746A59/@EntryIndexedValue"><NamingElement Priority="14" Title="Other constants"><Descriptor Static="True" Constexpr="Indeterminate" Const="True" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="class field" /><type Name="local variable" /><type Name="struct field" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=50D2535711CE1A43A3B06EF841C36CFD/@EntryIndexedValue"><NamingElement Priority="13" Title="Enum members"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="scoped enumerator" /><type Name="unscoped enumerator" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=6AD3BADA1260CC4D840AB26323C51827/@EntryIndexedValue"><NamingElement Priority="15" Title="Global constants"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="True" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="global variable" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=904CDCA174AACE4AA52660A247CDF9A0/@EntryIndexedValue"><NamingElement Priority="7" Title="Global variables"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="global variable" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=95BCDE767C97B64DB3DAE800DBBBC758/@EntryIndexedValue"><NamingElement Priority="5" Title="Parameters"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="function parameter" /><type Name="lambda parameter" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=C03AE454FC2CBA43819AC75E4D6C9C8C/@EntryIndexedValue"><NamingElement Priority="1" Title="Classes and structs"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="__interface" /><type Name="class" /><type Name="struct" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=D49E31C610641E4CAD0407DB79ACC851/@EntryIndexedValue"><NamingElement Priority="8" Title="Global functions"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="global function" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=D73FBB3529BC5449B6C85BB37B26A8D4/@EntryIndexedValue"><NamingElement Priority="16" Title="Namespaces"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="namespace" /><type Name="namespace alias" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=DA41807CE47AEB4CBE1724C44D0B786E/@EntryIndexedValue"><NamingElement Priority="6" Title="Local variables"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="local variable" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=DDF30C9A1DA74B4DBBC56D25FDF886AA/@EntryIndexedValue"><NamingElement Priority="10" Title="Class and struct fields"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="class field" /><type Name="struct field" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="aaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=EF70A6BF54ACE446971DDB32344C25A3/@EntryIndexedValue"><NamingElement Priority="12" Title="Union members"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="union member" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNamingOptions/Rules/=F37818C54C323A4A80B1A478629985AE/@EntryIndexedValue"><NamingElement Priority="2" Title="Enums"><Descriptor Static="Indeterminate" Constexpr="Indeterminate" Const="Indeterminate" Volatile="Indeterminate" Accessibility="NOT_APPLICABLE"><type Name="enum" /></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></NamingElement></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ARGB/@EntryIndexedValue">ARGB</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ARGB/@EntryIndexedValue">ARGB</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LO/@EntryIndexedValue">LO</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LO/@EntryIndexedValue">LO</s:String>
|
||||||
@@ -213,6 +231,7 @@
|
|||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=YZ/@EntryIndexedValue">YZ</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=YZ/@EntryIndexedValue">YZ</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="_" Suffix="" Style="aaBb" /></Policy></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="_" Suffix="" Style="aaBb" /></Policy></s:String>
|
||||||
<s:String x:Key="/Default/Environment/Hierarchy/PsiConfigurationSettingsKey/CustomLocation/@EntryValue">C:\Users\Wojtek\AppData\Local\JetBrains\Transient\ReSharperPlatformVs15\v08_f9eacea9\SolutionCaches</s:String>
|
<s:String x:Key="/Default/Environment/Hierarchy/PsiConfigurationSettingsKey/CustomLocation/@EntryValue">C:\Users\Wojtek\AppData\Local\JetBrains\Transient\ReSharperPlatformVs15\v08_f9eacea9\SolutionCaches</s:String>
|
||||||
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECpp_002ECodeStyle_002ENaming_002ECppNamingOptionsMigration/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECpp_002ECodeStyle_002ESettingsUpgrade_002EFunctionReturnStyleSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECpp_002ECodeStyle_002ESettingsUpgrade_002EFunctionReturnStyleSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECpp_002ECodeStyle_002ESettingsUpgrade_002ENamespaceIndentationSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECpp_002ECodeStyle_002ESettingsUpgrade_002ENamespaceIndentationSettingsUpgrader/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Linux/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=x64 -platform=Linux --buildTargets=FlaxEditor
|
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
<!-- Please search existing issues for potential duplicates before filing yours:
|
|
||||||
https://github.com/flaxengine/FlaxEngine/issues?q=is%3Aissue
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Issue description:**
|
|
||||||
<!-- What happened, and what was expected. -->
|
|
||||||
<!-- Log file, can be found in the project directory's `Logs` folder (optional) -->
|
|
||||||
|
|
||||||
**Steps to reproduce:**
|
|
||||||
<!-- Enter minimal reproduction steps if available. -->
|
|
||||||
|
|
||||||
|
|
||||||
**Minimal reproduction project:**
|
|
||||||
<!-- Recommended as it greatly speeds up debugging. Drag and drop a zip archive to upload it. -->
|
|
||||||
|
|
||||||
|
|
||||||
**Flax version:**
|
|
||||||
<!-- Specify version number. -->
|
|
||||||
|
|
||||||
@@ -57,9 +57,9 @@ Follow the instructions below to compile and run the engine from source.
|
|||||||
* Arch: `sudo pacman -S git git-lfs`
|
* Arch: `sudo pacman -S git git-lfs`
|
||||||
* `git-lfs install`
|
* `git-lfs install`
|
||||||
* Install the required packages:
|
* Install the required packages:
|
||||||
* Ubuntu: `sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev zlib1g-dev zenity wayland-protocols libportal-dev`
|
* Ubuntu: `sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev zlib1g-dev`
|
||||||
* Fedora: `sudo dnf install libX11-devel libXcursor-devel libXinerama-devel ghc-zlib-devel zenity wayland-protocols-devel libportal`
|
* Fedora: `sudo dnf install libX11-devel libXcursor-devel libXinerama-devel ghc-zlib-devel`
|
||||||
* Arch: `sudo pacman -S base-devel libx11 libxcursor libxinerama zlib zenity wayland-protocols libportal`
|
* Arch: `sudo pacman -S base-devel libx11 libxcursor libxinerama zlib`
|
||||||
* Install Clang compiler (version 6 or later):
|
* Install Clang compiler (version 6 or later):
|
||||||
* Ubuntu: `sudo apt-get install clang lldb lld`
|
* Ubuntu: `sudo apt-get install clang lldb lld`
|
||||||
* Fedora: `sudo dnf install clang llvm lldb lld`
|
* Fedora: `sudo dnf install clang llvm lldb lld`
|
||||||
|
|||||||
@@ -117,7 +117,8 @@ namespace FlaxEditor.Content.Create
|
|||||||
|
|
||||||
private static bool IsValid(Type type)
|
private static bool IsValid(Type type)
|
||||||
{
|
{
|
||||||
return (type.IsPublic || type.IsNestedPublic) && !type.IsAbstract && !type.IsGenericType;
|
var controlTypes = Editor.Instance.CodeEditing.Controls.Get();
|
||||||
|
return (type.IsPublic || type.IsNestedPublic) && !type.IsAbstract && !type.IsGenericType && controlTypes.Contains(new ScriptType(type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,6 @@ class PlatformTools;
|
|||||||
#define GAME_BUILD_DOTNET_RUNTIME_MAX_VER 9
|
#define GAME_BUILD_DOTNET_RUNTIME_MAX_VER 9
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OFFICIAL_BUILD
|
|
||||||
// Use the fixed .NET SDK version in packaged builds for compatibility (FlaxGame is precompiled with it)
|
|
||||||
#define GAME_BUILD_DOTNET_VER TEXT("-dotnet=" MACRO_TO_STR(GAME_BUILD_DOTNET_RUNTIME_MIN_VER))
|
|
||||||
#else
|
|
||||||
#define GAME_BUILD_DOTNET_VER TEXT("")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Game building options. Used as flags.
|
/// Game building options. Used as flags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -374,6 +367,8 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void GetBuildPlatformName(const Char*& platform, const Char*& architecture) const;
|
void GetBuildPlatformName(const Char*& platform, const Char*& architecture) const;
|
||||||
|
|
||||||
|
String GetDotnetCommandArg() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -312,6 +312,14 @@ void CookingData::GetBuildPlatformName(const Char*& platform, const Char*& archi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String CookingData::GetDotnetCommandArg() const
|
||||||
|
{
|
||||||
|
int32 version = Tools->GetDotnetVersion();
|
||||||
|
if (version == 0)
|
||||||
|
return String::Empty;
|
||||||
|
return String::Format(TEXT("-dotnet={}"), version);
|
||||||
|
}
|
||||||
|
|
||||||
void CookingData::StepProgress(const String& info, const float stepProgress) const
|
void CookingData::StepProgress(const String& info, const float stepProgress) const
|
||||||
{
|
{
|
||||||
const float singleStepProgress = 1.0f / (StepsCount + 1);
|
const float singleStepProgress = 1.0f / (StepsCount + 1);
|
||||||
@@ -675,8 +683,7 @@ bool GameCookerImpl::Build()
|
|||||||
|
|
||||||
MCore::Thread::Attach();
|
MCore::Thread::Attach();
|
||||||
|
|
||||||
// Build Started
|
// Build start
|
||||||
if (!EnumHasAnyFlags(data.Options, BuildOptions::NoCook))
|
|
||||||
{
|
{
|
||||||
CallEvent(GameCooker::EventType::BuildStarted);
|
CallEvent(GameCooker::EventType::BuildStarted);
|
||||||
data.Tools->OnBuildStarted(data);
|
data.Tools->OnBuildStarted(data);
|
||||||
@@ -749,8 +756,8 @@ bool GameCookerImpl::Build()
|
|||||||
}
|
}
|
||||||
IsRunning = false;
|
IsRunning = false;
|
||||||
CancelFlag = 0;
|
CancelFlag = 0;
|
||||||
if (!EnumHasAnyFlags(data.Options, BuildOptions::NoCook))
|
|
||||||
{
|
{
|
||||||
|
// Build end
|
||||||
for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++)
|
for (int32 stepIndex = 0; stepIndex < Steps.Count(); stepIndex++)
|
||||||
Steps[stepIndex]->OnBuildEnded(data, failed);
|
Steps[stepIndex]->OnBuildEnded(data, failed);
|
||||||
data.Tools->OnBuildEnded(data, failed);
|
data.Tools->OnBuildEnded(data, failed);
|
||||||
|
|||||||
@@ -195,4 +195,9 @@ bool GDKPlatformTools::OnPostProcess(CookingData& data, GDKPlatformSettings* pla
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 GDKPlatformTools::GetDotnetVersion() const
|
||||||
|
{
|
||||||
|
return GAME_BUILD_DOTNET_RUNTIME_MIN_VER;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
// [PlatformTools]
|
// [PlatformTools]
|
||||||
|
int32 GetDotnetVersion() const override;
|
||||||
DotNetAOTModes UseAOT() const override;
|
DotNetAOTModes UseAOT() const override;
|
||||||
bool OnDeployBinaries(CookingData& data) override;
|
bool OnDeployBinaries(CookingData& data) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -231,6 +231,8 @@ bool MacPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
LOG(Info, "Building app package...");
|
LOG(Info, "Building app package...");
|
||||||
{
|
{
|
||||||
const String dmgPath = data.OriginalOutputPath / appName + TEXT(".dmg");
|
const String dmgPath = data.OriginalOutputPath / appName + TEXT(".dmg");
|
||||||
|
if (FileSystem::FileExists(dmgPath))
|
||||||
|
FileSystem::DeleteFile(dmgPath);
|
||||||
CreateProcessSettings procSettings;
|
CreateProcessSettings procSettings;
|
||||||
procSettings.HiddenWindow = true;
|
procSettings.HiddenWindow = true;
|
||||||
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
||||||
|
|||||||
@@ -528,6 +528,9 @@ bool WindowsPlatformTools::OnDeployBinaries(CookingData& data)
|
|||||||
|
|
||||||
void WindowsPlatformTools::OnBuildStarted(CookingData& data)
|
void WindowsPlatformTools::OnBuildStarted(CookingData& data)
|
||||||
{
|
{
|
||||||
|
if (EnumHasAllFlags(data.Options, BuildOptions::NoCook))
|
||||||
|
return;
|
||||||
|
|
||||||
// Remove old executable
|
// Remove old executable
|
||||||
Array<String> files;
|
Array<String> files;
|
||||||
FileSystem::DirectoryGetFiles(files, data.NativeCodeOutputPath, TEXT("*.exe"), DirectorySearchOption::TopDirectoryOnly);
|
FileSystem::DirectoryGetFiles(files, data.NativeCodeOutputPath, TEXT("*.exe"), DirectorySearchOption::TopDirectoryOnly);
|
||||||
|
|||||||
@@ -70,6 +70,20 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
virtual ArchitectureType GetArchitecture() const = 0;
|
virtual ArchitectureType GetArchitecture() const = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the .Net version to use for the cooked game.
|
||||||
|
/// </summary>
|
||||||
|
virtual int32 GetDotnetVersion() const
|
||||||
|
{
|
||||||
|
#if OFFICIAL_BUILD
|
||||||
|
// Use the fixed .NET SDK version in packaged builds for compatibility (FlaxGame is precompiled with it)
|
||||||
|
return GAME_BUILD_DOTNET_RUNTIME_MIN_VER;
|
||||||
|
#else
|
||||||
|
// Use the highest version found on a system (Flax.Build will decide)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the value indicating whenever platform requires AOT (needs C# assemblies to be precompiled).
|
/// Gets the value indicating whenever platform requires AOT (needs C# assemblies to be precompiled).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ bool CompileScriptsStep::Perform(CookingData& data)
|
|||||||
const String logFile = data.CacheDirectory / TEXT("CompileLog.txt");
|
const String logFile = data.CacheDirectory / TEXT("CompileLog.txt");
|
||||||
auto args = String::Format(
|
auto args = String::Format(
|
||||||
TEXT("-log -logfile=\"{4}\" -build -mutex -buildtargets={0} -platform={1} -arch={2} -configuration={3} -aotMode={5} {6}"),
|
TEXT("-log -logfile=\"{4}\" -build -mutex -buildtargets={0} -platform={1} -arch={2} -configuration={3} -aotMode={5} {6}"),
|
||||||
target, platform, architecture, configuration, logFile, ToString(data.Tools->UseAOT()), GAME_BUILD_DOTNET_VER);
|
target, platform, architecture, configuration, logFile, ToString(data.Tools->UseAOT()), data.GetDotnetCommandArg());
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS
|
||||||
if (data.Platform == BuildPlatform::LinuxX64)
|
if (data.Platform == BuildPlatform::LinuxX64)
|
||||||
#elif PLATFORM_LINUX
|
#elif PLATFORM_LINUX
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
{
|
{
|
||||||
// Ask Flax.Build to provide .NET SDK location for the current platform
|
// Ask Flax.Build to provide .NET SDK location for the current platform
|
||||||
String sdks;
|
String sdks;
|
||||||
bool failed = ScriptsBuilder::RunBuildTool(String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printSDKs {}"), GAME_BUILD_DOTNET_VER), data.CacheDirectory);
|
bool failed = ScriptsBuilder::RunBuildTool(String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printSDKs {}"), data.GetDotnetCommandArg()), data.CacheDirectory);
|
||||||
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
||||||
int32 idx = sdks.Find(TEXT("DotNetSdk, "), StringSearchCase::CaseSensitive);
|
int32 idx = sdks.Find(TEXT("DotNetSdk, "), StringSearchCase::CaseSensitive);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
@@ -200,7 +200,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
String sdks;
|
String sdks;
|
||||||
const Char *platformName, *archName;
|
const Char *platformName, *archName;
|
||||||
data.GetBuildPlatformName(platformName, archName);
|
data.GetBuildPlatformName(platformName, archName);
|
||||||
String args = String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printDotNetRuntime -platform={} -arch={} {}"), platformName, archName, GAME_BUILD_DOTNET_VER);
|
String args = String::Format(TEXT("-log -logMessagesOnly -logFileWithConsole -logfile=SDKs.txt -printDotNetRuntime -platform={} -arch={} {}"), platformName, archName, data.GetDotnetCommandArg());
|
||||||
bool failed = ScriptsBuilder::RunBuildTool(args, data.CacheDirectory);
|
bool failed = ScriptsBuilder::RunBuildTool(args, data.CacheDirectory);
|
||||||
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
failed |= File::ReadAllText(data.CacheDirectory / TEXT("SDKs.txt"), sdks);
|
||||||
Array<String> parts;
|
Array<String> parts;
|
||||||
@@ -244,10 +244,13 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
if (version.IsEmpty())
|
if (version.IsEmpty())
|
||||||
{
|
{
|
||||||
|
int32 minVer = GAME_BUILD_DOTNET_RUNTIME_MIN_VER, maxVer = GAME_BUILD_DOTNET_RUNTIME_MAX_VER;
|
||||||
if (srcDotnetFromEngine)
|
if (srcDotnetFromEngine)
|
||||||
{
|
{
|
||||||
// Detect version from runtime files inside Engine Platform folder
|
// Detect version from runtime files inside Engine Platform folder
|
||||||
for (int32 i = GAME_BUILD_DOTNET_RUNTIME_MAX_VER; i >= GAME_BUILD_DOTNET_RUNTIME_MIN_VER; i--)
|
if (data.Tools->GetDotnetVersion() != 0)
|
||||||
|
minVer = maxVer = data.Tools->GetDotnetVersion();
|
||||||
|
for (int32 i = maxVer; i >= minVer; i--)
|
||||||
{
|
{
|
||||||
// Check runtime files inside Engine Platform folder
|
// Check runtime files inside Engine Platform folder
|
||||||
String testPath1 = srcDotnet / String::Format(TEXT("lib/net{}.0"), i);
|
String testPath1 = srcDotnet / String::Format(TEXT("lib/net{}.0"), i);
|
||||||
@@ -262,7 +265,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
if (version.IsEmpty())
|
if (version.IsEmpty())
|
||||||
{
|
{
|
||||||
data.Error(String::Format(TEXT("Failed to find supported .NET {} version for the current host platform."), GAME_BUILD_DOTNET_RUNTIME_MIN_VER));
|
data.Error(String::Format(TEXT("Failed to find supported .NET {} version (min {}) for the current host platform."), maxVer, minVer));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,7 +367,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
const String logFile = data.CacheDirectory / TEXT("StripDotnetLibs.txt");
|
const String logFile = data.CacheDirectory / TEXT("StripDotnetLibs.txt");
|
||||||
String args = String::Format(
|
String args = String::Format(
|
||||||
TEXT("-log -logfile=\"{}\" -runDotNetClassLibStripping -mutex -binaries=\"{}\" {}"),
|
TEXT("-log -logfile=\"{}\" -runDotNetClassLibStripping -mutex -binaries=\"{}\" {}"),
|
||||||
logFile, data.DataOutputPath, GAME_BUILD_DOTNET_VER);
|
logFile, data.DataOutputPath, data.GetDotnetCommandArg());
|
||||||
for (const String& define : data.CustomDefines)
|
for (const String& define : data.CustomDefines)
|
||||||
{
|
{
|
||||||
args += TEXT(" -D");
|
args += TEXT(" -D");
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
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)
|
if (aotMode == DotNetAOTModes::None || EnumHasAllFlags(data.Options, BuildOptions::NoCook))
|
||||||
return;
|
return;
|
||||||
const auto& buildSettings = *BuildSettings::Get();
|
const auto& buildSettings = *BuildSettings::Get();
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ bool PrecompileAssembliesStep::Perform(CookingData& data)
|
|||||||
const String logFile = data.CacheDirectory / TEXT("AOTLog.txt");
|
const String logFile = data.CacheDirectory / TEXT("AOTLog.txt");
|
||||||
String args = String::Format(
|
String args = String::Format(
|
||||||
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\" {}"),
|
TEXT("-log -logfile=\"{}\" -runDotNetAOT -mutex -platform={} -arch={} -configuration={} -aotMode={} -binaries=\"{}\" -intermediate=\"{}\" {}"),
|
||||||
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath, GAME_BUILD_DOTNET_VER);
|
logFile, platform, architecture, configuration, ToString(aotMode), data.DataOutputPath, data.ManagedCodeOutputPath, data.GetDotnetCommandArg());
|
||||||
if (!buildSettings.SkipUnusedDotnetLibsPackaging)
|
if (!buildSettings.SkipUnusedDotnetLibsPackaging)
|
||||||
args += TEXT(" -skipUnusedDotnetLibs=false"); // Run AOT on whole class library (not just used libs)
|
args += TEXT(" -skipUnusedDotnetLibs=false"); // Run AOT on whole class library (not just used libs)
|
||||||
for (const String& define : data.CustomDefines)
|
for (const String& define : data.CustomDefines)
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ namespace FlaxEditor
|
|||||||
private readonly CustomEditorPresenter _presenter;
|
private readonly CustomEditorPresenter _presenter;
|
||||||
private CustomEditorWindow _customEditor;
|
private CustomEditorWindow _customEditor;
|
||||||
|
|
||||||
public Win(CustomEditorWindow customEditor)
|
public Win(CustomEditorWindow customEditor, bool hideOnClose, ScrollBars scrollBars)
|
||||||
: base(Editor.Instance, false, ScrollBars.Vertical)
|
: base(Editor.Instance, hideOnClose, scrollBars)
|
||||||
{
|
{
|
||||||
Title = customEditor.GetType().Name;
|
Title = customEditor.GetType().Name;
|
||||||
_customEditor = customEditor;
|
_customEditor = customEditor;
|
||||||
@@ -64,9 +64,9 @@ namespace FlaxEditor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="CustomEditorWindow"/> class.
|
/// Initializes a new instance of the <see cref="CustomEditorWindow"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected CustomEditorWindow()
|
protected CustomEditorWindow(bool hideOnClose = false, ScrollBars scrollBars = ScrollBars.Vertical)
|
||||||
{
|
{
|
||||||
_win = new Win(this);
|
_win = new Win(this, hideOnClose, scrollBars);
|
||||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -749,6 +749,15 @@ namespace FlaxEditor.CustomEditors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Actor FindActor(CustomEditor editor)
|
||||||
|
{
|
||||||
|
if (editor.Values[0] is Actor actor)
|
||||||
|
return actor;
|
||||||
|
if (editor.ParentEditor != null)
|
||||||
|
return FindActor(editor.ParentEditor);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private Actor FindPrefabRoot(CustomEditor editor)
|
private Actor FindPrefabRoot(CustomEditor editor)
|
||||||
{
|
{
|
||||||
if (editor.Values[0] is Actor actor)
|
if (editor.Values[0] is Actor actor)
|
||||||
@@ -767,32 +776,35 @@ namespace FlaxEditor.CustomEditors
|
|||||||
return FindPrefabRoot(actor.Parent);
|
return FindPrefabRoot(actor.Parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SceneObject FindObjectWithPrefabObjectId(Actor actor, ref Guid prefabObjectId)
|
private SceneObject FindObjectWithPrefabObjectId(Actor actor, ref Guid prefabObjectId, Actor endPoint)
|
||||||
{
|
{
|
||||||
|
var visited = new HashSet<Actor>();
|
||||||
|
return FindObjectWithPrefabObjectId(actor, ref prefabObjectId, endPoint, visited);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SceneObject FindObjectWithPrefabObjectId(Actor actor, ref Guid prefabObjectId, Actor endPoint, HashSet<Actor> visited)
|
||||||
|
{
|
||||||
|
if (visited.Contains(actor) || actor is Scene || actor == endPoint)
|
||||||
|
return null;
|
||||||
if (actor.PrefabObjectID == prefabObjectId)
|
if (actor.PrefabObjectID == prefabObjectId)
|
||||||
return actor;
|
return actor;
|
||||||
|
|
||||||
for (int i = 0; i < actor.ScriptsCount; i++)
|
for (int i = 0; i < actor.ScriptsCount; i++)
|
||||||
{
|
{
|
||||||
if (actor.GetScript(i).PrefabObjectID == prefabObjectId)
|
var script = actor.GetScript(i);
|
||||||
{
|
if (script != null && script.PrefabObjectID == prefabObjectId)
|
||||||
var a = actor.GetScript(i);
|
return script;
|
||||||
if (a != null)
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < actor.ChildrenCount; i++)
|
for (int i = 0; i < actor.ChildrenCount; i++)
|
||||||
{
|
{
|
||||||
if (actor.GetChild(i).PrefabObjectID == prefabObjectId)
|
var child = actor.GetChild(i);
|
||||||
{
|
if (child != null && child.PrefabObjectID == prefabObjectId)
|
||||||
var a = actor.GetChild(i);
|
return child;
|
||||||
if (a != null)
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
// Go up in the hierarchy
|
||||||
|
return FindObjectWithPrefabObjectId(actor.Parent, ref prefabObjectId, endPoint, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -826,7 +838,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
}
|
}
|
||||||
|
|
||||||
var prefabObjectId = referenceSceneObject.PrefabObjectID;
|
var prefabObjectId = referenceSceneObject.PrefabObjectID;
|
||||||
var prefabInstanceRef = FindObjectWithPrefabObjectId(prefabInstanceRoot, ref prefabObjectId);
|
var prefabInstanceRef = FindObjectWithPrefabObjectId(FindActor(this), ref prefabObjectId, prefabInstanceRoot);
|
||||||
if (prefabInstanceRef == null)
|
if (prefabInstanceRef == null)
|
||||||
{
|
{
|
||||||
Editor.LogWarning("Missing prefab instance reference in the prefab instance. Cannot revert to it.");
|
Editor.LogWarning("Missing prefab instance reference in the prefab instance. Cannot revert to it.");
|
||||||
|
|||||||
@@ -63,6 +63,11 @@ namespace FlaxEditor.CustomEditors
|
|||||||
/// Indication of if the properties window is locked on specific objects.
|
/// Indication of if the properties window is locked on specific objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool LockSelection { get; set; }
|
public bool LockSelection { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the scene editing context.
|
||||||
|
/// </summary>
|
||||||
|
public ISceneEditingContext SceneContext { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -87,8 +87,11 @@ namespace FlaxEditor.CustomEditors
|
|||||||
var targetTypeType = TypeUtils.GetType(targetType);
|
var targetTypeType = TypeUtils.GetType(targetType);
|
||||||
if (canUseRefPicker)
|
if (canUseRefPicker)
|
||||||
{
|
{
|
||||||
|
// TODO: add generic way of CustomEditor for ref pickers (use it on AssetRefEditor/GPUTextureEditor/...)
|
||||||
if (typeof(Asset).IsAssignableFrom(targetTypeType))
|
if (typeof(Asset).IsAssignableFrom(targetTypeType))
|
||||||
return new AssetRefEditor();
|
return new AssetRefEditor();
|
||||||
|
if (typeof(GPUTexture).IsAssignableFrom(targetTypeType))
|
||||||
|
return new GPUTextureEditor();
|
||||||
if (typeof(FlaxEngine.Object).IsAssignableFrom(targetTypeType))
|
if (typeof(FlaxEngine.Object).IsAssignableFrom(targetTypeType))
|
||||||
return new FlaxObjectRefEditor();
|
return new FlaxObjectRefEditor();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using FlaxEditor.Actions;
|
using FlaxEditor.Actions;
|
||||||
using FlaxEditor.CustomEditors.Editors;
|
using FlaxEditor.CustomEditors.Editors;
|
||||||
using FlaxEditor.CustomEditors.Elements;
|
using FlaxEditor.CustomEditors.Elements;
|
||||||
@@ -10,12 +7,14 @@ using FlaxEditor.GUI;
|
|||||||
using FlaxEditor.GUI.ContextMenu;
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
using FlaxEditor.GUI.Tree;
|
using FlaxEditor.GUI.Tree;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Windows;
|
|
||||||
using FlaxEditor.Windows.Assets;
|
using FlaxEditor.Windows.Assets;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Json;
|
using FlaxEngine.Json;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace FlaxEditor.CustomEditors.Dedicated
|
namespace FlaxEditor.CustomEditors.Dedicated
|
||||||
{
|
{
|
||||||
@@ -240,6 +239,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
node.TextColor = Color.OrangeRed;
|
node.TextColor = Color.OrangeRed;
|
||||||
node.Text = Utilities.Utils.GetPropertyNameUI(removed.PrefabObject.GetType().Name);
|
node.Text = Utilities.Utils.GetPropertyNameUI(removed.PrefabObject.GetType().Name);
|
||||||
}
|
}
|
||||||
|
// Removed Actor
|
||||||
|
else if (editor is RemovedActorDummy removedActor)
|
||||||
|
{
|
||||||
|
node.TextColor = Color.OrangeRed;
|
||||||
|
node.Text = $"{removedActor.PrefabObject.Name} ({Utilities.Utils.GetPropertyNameUI(removedActor.PrefabObject.GetType().Name)})";
|
||||||
|
}
|
||||||
// Actor or Script
|
// Actor or Script
|
||||||
else if (editor.Values[0] is SceneObject sceneObject)
|
else if (editor.Values[0] is SceneObject sceneObject)
|
||||||
{
|
{
|
||||||
@@ -295,16 +300,40 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
// Not used
|
// Not used
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class RemovedActorDummy : CustomEditor
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The removed prefab object (from the prefab default instance).
|
||||||
|
/// </summary>
|
||||||
|
public Actor PrefabObject;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The prefab instance's parent.
|
||||||
|
/// </summary>
|
||||||
|
public Actor ParentActor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The order of the removed actor in the parent.
|
||||||
|
/// </summary>
|
||||||
|
public int OrderInParent;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
|
{
|
||||||
|
// Not used
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private TreeNode ProcessDiff(CustomEditor editor, bool skipIfNotModified = true)
|
private TreeNode ProcessDiff(CustomEditor editor, bool skipIfNotModified = true)
|
||||||
{
|
{
|
||||||
// Special case for new Script added to actor
|
// Special case for new Script or child actor added to actor
|
||||||
if (editor.Values[0] is Script script && !script.HasPrefabLink)
|
if ((editor.Values[0] is Script script && !script.HasPrefabLink) || (editor.Values[0] is Actor a && !a.HasPrefabLink))
|
||||||
return CreateDiffNode(editor);
|
return CreateDiffNode(editor);
|
||||||
|
|
||||||
// Skip if no change detected
|
// Skip if no change detected
|
||||||
var isRefEdited = editor.Values.IsReferenceValueModified;
|
var isRefEdited = editor.Values.IsReferenceValueModified;
|
||||||
if (!isRefEdited && skipIfNotModified)
|
if (!isRefEdited && skipIfNotModified && editor is not ScriptsEditor)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
TreeNode result = null;
|
TreeNode result = null;
|
||||||
@@ -359,6 +388,44 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare child actors for removed actors.
|
||||||
|
if (editor is ActorEditor && editor.Values.HasReferenceValue && editor.Values.ReferenceValue is Actor prefabObjectActor)
|
||||||
|
{
|
||||||
|
var thisActor = editor.Values[0] as Actor;
|
||||||
|
for (int i = 0; i < prefabObjectActor.ChildrenCount; i++)
|
||||||
|
{
|
||||||
|
var prefabActorChild = prefabObjectActor.Children[i];
|
||||||
|
if (thisActor == null)
|
||||||
|
continue;
|
||||||
|
bool isRemoved = true;
|
||||||
|
for (int j = 0; j < thisActor.ChildrenCount; j++)
|
||||||
|
{
|
||||||
|
var actorChild = thisActor.Children[j];
|
||||||
|
if (actorChild.PrefabObjectID == prefabActorChild.PrefabObjectID)
|
||||||
|
{
|
||||||
|
isRemoved = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isRemoved)
|
||||||
|
{
|
||||||
|
var dummy = new RemovedActorDummy
|
||||||
|
{
|
||||||
|
PrefabObject = prefabActorChild,
|
||||||
|
ParentActor = thisActor,
|
||||||
|
OrderInParent = prefabActorChild.OrderInParent,
|
||||||
|
};
|
||||||
|
var child = CreateDiffNode(dummy);
|
||||||
|
if (result == null)
|
||||||
|
result = CreateDiffNode(editor);
|
||||||
|
result.AddChild(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (editor is ScriptsEditor && result != null && result.ChildrenCount == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,6 +505,15 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
Presenter.BuildLayoutOnUpdate();
|
Presenter.BuildLayoutOnUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void GetAllPrefabObjects(List<object> objects, Actor actor)
|
||||||
|
{
|
||||||
|
objects.Add(actor);
|
||||||
|
objects.AddRange(actor.Scripts);
|
||||||
|
var children = actor.Children;
|
||||||
|
foreach (var child in children)
|
||||||
|
GetAllPrefabObjects(objects, child);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnDiffRevert(CustomEditor editor)
|
private void OnDiffRevert(CustomEditor editor)
|
||||||
{
|
{
|
||||||
// Special case for removed Script from actor
|
// Special case for removed Script from actor
|
||||||
@@ -459,6 +535,22 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special case for reverting removed Actors
|
||||||
|
if (editor is RemovedActorDummy removedActor)
|
||||||
|
{
|
||||||
|
Editor.Log("Reverting removed actor changes to prefab (adding it)");
|
||||||
|
|
||||||
|
var parentActor = removedActor.ParentActor;
|
||||||
|
var restored = parentActor.AddChild(removedActor.PrefabObject.GetType());
|
||||||
|
var prefabId = parentActor.PrefabID;
|
||||||
|
var prefabObjectId = removedActor.PrefabObject.PrefabObjectID;
|
||||||
|
string data = JsonSerializer.Serialize(removedActor.PrefabObject);
|
||||||
|
JsonSerializer.Deserialize(restored, data);
|
||||||
|
Presenter.Owner.SceneContext.Spawn(restored, parentActor, removedActor.OrderInParent);
|
||||||
|
Actor.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), ref prefabId, ref prefabObjectId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Special case for new Script added to actor
|
// Special case for new Script added to actor
|
||||||
if (editor.Values[0] is Script script && !script.HasPrefabLink)
|
if (editor.Values[0] is Script script && !script.HasPrefabLink)
|
||||||
{
|
{
|
||||||
@@ -470,8 +562,37 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Special case for new Actor added to actor
|
||||||
|
if (editor.Values[0] is Actor a && !a.HasPrefabLink)
|
||||||
|
{
|
||||||
|
Editor.Log("Reverting added actor changes to prefab (removing it)");
|
||||||
|
|
||||||
editor.RevertToReferenceValue();
|
// TODO: Keep previous selection.
|
||||||
|
var context = Presenter.Owner.SceneContext;
|
||||||
|
context.Select(SceneGraph.SceneGraphFactory.FindNode(a.ID));
|
||||||
|
context.DeleteSelection();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Presenter.Undo != null && Presenter.Undo.Enabled)
|
||||||
|
{
|
||||||
|
var thisActor = (Actor)Values[0];
|
||||||
|
var rootActor = thisActor.IsPrefabRoot ? thisActor : thisActor.GetPrefabRoot();
|
||||||
|
var prefabObjects = new List<object>();
|
||||||
|
GetAllPrefabObjects(prefabObjects, rootActor);
|
||||||
|
using (new UndoMultiBlock(Presenter.Undo, prefabObjects, "Revert to Prefab"))
|
||||||
|
{
|
||||||
|
editor.RevertToReferenceValue();
|
||||||
|
editor.RefreshInternal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
editor.RevertToReferenceValue();
|
||||||
|
editor.RefreshInternal();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
public class AudioSourceEditor : ActorEditor
|
public class AudioSourceEditor : ActorEditor
|
||||||
{
|
{
|
||||||
private Label _infoLabel;
|
private Label _infoLabel;
|
||||||
|
private Slider _slider;
|
||||||
|
private AudioSource.States _slideStartState;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
@@ -28,6 +30,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
_infoLabel = playbackGroup.Label(string.Empty).Label;
|
_infoLabel = playbackGroup.Label(string.Empty).Label;
|
||||||
_infoLabel.AutoHeight = true;
|
_infoLabel.AutoHeight = true;
|
||||||
|
|
||||||
|
// Play back slider
|
||||||
|
var sliderElement = playbackGroup.CustomContainer<Slider>();
|
||||||
|
_slider = sliderElement.CustomControl;
|
||||||
|
_slider.ThumbSize = new Float2(_slider.ThumbSize.X * 0.5f, _slider.ThumbSize.Y);
|
||||||
|
_slider.SlidingStart += OnSlidingStart;
|
||||||
|
_slider.SlidingEnd += OnSlidingEnd;
|
||||||
|
|
||||||
var grid = playbackGroup.UniformGrid();
|
var grid = playbackGroup.UniformGrid();
|
||||||
var gridControl = grid.CustomControl;
|
var gridControl = grid.CustomControl;
|
||||||
gridControl.ClipChildren = false;
|
gridControl.ClipChildren = false;
|
||||||
@@ -40,6 +49,38 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnSlidingEnd()
|
||||||
|
{
|
||||||
|
foreach (var value in Values)
|
||||||
|
{
|
||||||
|
if (value is AudioSource audioSource && audioSource.Clip)
|
||||||
|
{
|
||||||
|
switch (_slideStartState)
|
||||||
|
{
|
||||||
|
case AudioSource.States.Playing:
|
||||||
|
audioSource.Play();
|
||||||
|
break;
|
||||||
|
case AudioSource.States.Paused:
|
||||||
|
case AudioSource.States.Stopped:
|
||||||
|
audioSource.Pause();
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSlidingStart()
|
||||||
|
{
|
||||||
|
foreach (var value in Values)
|
||||||
|
{
|
||||||
|
if (value is AudioSource audioSource && audioSource.Clip)
|
||||||
|
{
|
||||||
|
_slideStartState = audioSource.State;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Refresh()
|
public override void Refresh()
|
||||||
{
|
{
|
||||||
@@ -51,7 +92,29 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
foreach (var value in Values)
|
foreach (var value in Values)
|
||||||
{
|
{
|
||||||
if (value is AudioSource audioSource && audioSource.Clip)
|
if (value is AudioSource audioSource && audioSource.Clip)
|
||||||
|
{
|
||||||
text += $"Time: {audioSource.Time:##0.0}s / {audioSource.Clip.Length:##0.0}s\n";
|
text += $"Time: {audioSource.Time:##0.0}s / {audioSource.Clip.Length:##0.0}s\n";
|
||||||
|
_slider.Maximum = audioSource.Clip.Length;
|
||||||
|
_slider.Minimum = 0;
|
||||||
|
if (_slider.IsSliding)
|
||||||
|
{
|
||||||
|
if (audioSource.State != AudioSource.States.Playing)
|
||||||
|
{
|
||||||
|
// Play to move slider correctly
|
||||||
|
audioSource.Play();
|
||||||
|
audioSource.Time = _slider.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
audioSource.Time = _slider.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_slider.Value = audioSource.Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_infoLabel.Text = text;
|
_infoLabel.Text = text;
|
||||||
}
|
}
|
||||||
|
|||||||
68
Source/Editor/CustomEditors/Dedicated/GPUTextureEditor.cs
Normal file
68
Source/Editor/CustomEditors/Dedicated/GPUTextureEditor.cs
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
|
namespace FlaxEditor.CustomEditors.Dedicated
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Basic editor/viewer for <see cref="GPUTexture"/>.
|
||||||
|
/// </summary>
|
||||||
|
[CustomEditor(typeof(GPUTexture)), DefaultEditor]
|
||||||
|
public class GPUTextureEditor : CustomEditor
|
||||||
|
{
|
||||||
|
private Image _image;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override DisplayStyle Style => DisplayStyle.Inline;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
|
{
|
||||||
|
_image = new Image
|
||||||
|
{
|
||||||
|
Brush = new GPUTextureBrush(),
|
||||||
|
Size = new Float2(200, 100),
|
||||||
|
Parent = layout.ContainerControl,
|
||||||
|
};
|
||||||
|
_image.Clicked += OnImageClicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnImageClicked(Image image, MouseButton button)
|
||||||
|
{
|
||||||
|
var texture = Values[0] as GPUTexture;
|
||||||
|
if (!texture || button != MouseButton.Right)
|
||||||
|
return;
|
||||||
|
var menu = new ContextMenu();
|
||||||
|
menu.AddButton("Save...", () => Screenshot.Capture(Values[0] as GPUTexture));
|
||||||
|
menu.AddButton("Enlarge", () => _image.Size *= 2);
|
||||||
|
menu.AddButton("Shrink", () => _image.Size /= 2).Enabled = _image.Height > 32;
|
||||||
|
var location = image.PointFromScreen(Input.MouseScreenPosition);
|
||||||
|
menu.Show(image, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void Refresh()
|
||||||
|
{
|
||||||
|
base.Refresh();
|
||||||
|
|
||||||
|
var texture = Values[0] as GPUTexture;
|
||||||
|
((GPUTextureBrush)_image.Brush).Texture = texture;
|
||||||
|
if (texture)
|
||||||
|
{
|
||||||
|
var desc = texture.Description;
|
||||||
|
#if BUILD_RELEASE
|
||||||
|
var name = string.Empty;
|
||||||
|
#else
|
||||||
|
var name = texture.Name;
|
||||||
|
#endif
|
||||||
|
_image.TooltipText = $"{name}\nType: {texture.ResourceType}\nSize: {desc.Width}x{desc.Height}\nFormat: {desc.Format}\nMemory: {Utilities.Utils.FormatBytesCount(texture.MemoryUsage)}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_image.TooltipText = "None";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
{
|
{
|
||||||
ScriptName = scriptName;
|
ScriptName = scriptName;
|
||||||
TooltipText = "Create a new script";
|
TooltipText = "Create a new script";
|
||||||
|
DrawHighlights = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
var buttonHeight = (textSize.Y < 18) ? 18 : textSize.Y + 4;
|
var buttonHeight = (textSize.Y < 18) ? 18 : textSize.Y + 4;
|
||||||
_addScriptsButton = new Button
|
_addScriptsButton = new Button
|
||||||
{
|
{
|
||||||
TooltipText = "Add new scripts to the actor",
|
TooltipText = "Add new scripts to the actor.",
|
||||||
AnchorPreset = AnchorPresets.MiddleCenter,
|
AnchorPreset = AnchorPresets.MiddleCenter,
|
||||||
Text = buttonText,
|
Text = buttonText,
|
||||||
Parent = this,
|
Parent = this,
|
||||||
@@ -114,7 +115,16 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
cm.TextChanged += text =>
|
cm.TextChanged += text =>
|
||||||
{
|
{
|
||||||
if (!IsValidScriptName(text))
|
if (!IsValidScriptName(text))
|
||||||
|
{
|
||||||
|
// Remove NewScriptItems
|
||||||
|
List<Control> newScriptItems = cm.ItemsPanel.Children.FindAll(c => c is NewScriptItem);
|
||||||
|
foreach (var item in newScriptItems)
|
||||||
|
{
|
||||||
|
cm.ItemsPanel.RemoveChild(item);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (!cm.ItemsPanel.Children.Any(x => x.Visible && x is not NewScriptItem))
|
if (!cm.ItemsPanel.Children.Any(x => x.Visible && x is not NewScriptItem))
|
||||||
{
|
{
|
||||||
// If there are no visible items, that means the search failed so we can find the create script button or create one if it's the first time
|
// If there are no visible items, that means the search failed so we can find the create script button or create one if it's the first time
|
||||||
@@ -876,7 +886,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
// Add drag button to the group
|
// Add drag button to the group
|
||||||
var scriptDrag = new DragImage
|
var scriptDrag = new DragImage
|
||||||
{
|
{
|
||||||
TooltipText = "Script reference",
|
TooltipText = "Script reference.",
|
||||||
AutoFocus = true,
|
AutoFocus = true,
|
||||||
IsScrollable = false,
|
IsScrollable = false,
|
||||||
Color = FlaxEngine.GUI.Style.Current.ForegroundGrey,
|
Color = FlaxEngine.GUI.Style.Current.ForegroundGrey,
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
_linkButton = new Button
|
_linkButton = new Button
|
||||||
{
|
{
|
||||||
BackgroundBrush = new SpriteBrush(Editor.Instance.Icons.Link32),
|
|
||||||
Parent = LinkedLabel,
|
Parent = LinkedLabel,
|
||||||
Width = 18,
|
Width = 18,
|
||||||
Height = 18,
|
Height = 18,
|
||||||
@@ -189,6 +188,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
_linkButton.SetColors(backgroundColor);
|
_linkButton.SetColors(backgroundColor);
|
||||||
_linkButton.BorderColor = _linkButton.BorderColorSelected = _linkButton.BorderColorHighlighted = Color.Transparent;
|
_linkButton.BorderColor = _linkButton.BorderColorSelected = _linkButton.BorderColorHighlighted = Color.Transparent;
|
||||||
_linkButton.TooltipText = LinkValues ? "Unlinks scale components from uniform scaling" : "Links scale components for uniform scaling";
|
_linkButton.TooltipText = LinkValues ? "Unlinks scale components from uniform scaling" : "Links scale components for uniform scaling";
|
||||||
|
_linkButton.BackgroundBrush = new SpriteBrush(LinkValues ? Editor.Instance.Icons.Link32 : Editor.Instance.Icons.BrokenLink32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
menu.ItemsContainer.RemoveChildren();
|
menu.ItemsContainer.RemoveChildren();
|
||||||
|
|
||||||
menu.AddButton("Copy", linkedEditor.Copy);
|
menu.AddButton("Copy", linkedEditor.Copy);
|
||||||
var b = menu.AddButton("Paste", linkedEditor.Paste);
|
var b = menu.AddButton("Duplicate", () => Editor.Duplicate(Index));
|
||||||
|
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly && Editor._canResize;
|
||||||
|
b = menu.AddButton("Paste", linkedEditor.Paste);
|
||||||
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
|
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
|
||||||
|
|
||||||
menu.AddSeparator();
|
menu.AddSeparator();
|
||||||
@@ -404,8 +406,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var menu = new ContextMenu();
|
var menu = new ContextMenu();
|
||||||
|
|
||||||
menu.AddButton("Copy", linkedEditor.Copy);
|
menu.AddButton("Copy", linkedEditor.Copy);
|
||||||
|
var b = menu.AddButton("Duplicate", () => Editor.Duplicate(Index));
|
||||||
|
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly && Editor._canResize;
|
||||||
var paste = menu.AddButton("Paste", linkedEditor.Paste);
|
var paste = menu.AddButton("Paste", linkedEditor.Paste);
|
||||||
paste.Enabled = linkedEditor.CanPaste;
|
paste.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
|
||||||
|
|
||||||
if (_canReorder)
|
if (_canReorder)
|
||||||
{
|
{
|
||||||
@@ -418,7 +422,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
moveDownButton.Enabled = Index + 1 < Editor.Count;
|
moveDownButton.Enabled = Index + 1 < Editor.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.AddButton("Remove", OnRemoveClicked);
|
b = menu.AddButton("Remove", OnRemoveClicked);
|
||||||
|
b.Enabled = !Editor._readOnly && Editor._canResize;
|
||||||
|
|
||||||
menu.Show(panel, location);
|
menu.Show(panel, location);
|
||||||
}
|
}
|
||||||
@@ -741,6 +746,34 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
cloned[srcIndex] = tmp;
|
cloned[srcIndex] = tmp;
|
||||||
SetValue(cloned);
|
SetValue(cloned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Duplicates the list item.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index to duplicate.</param>
|
||||||
|
public void Duplicate(int index)
|
||||||
|
{
|
||||||
|
if (IsSetBlocked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var count = Count;
|
||||||
|
var newValues = Allocate(count + 1);
|
||||||
|
var oldValues = (IList)Values[0];
|
||||||
|
|
||||||
|
for (int i = 0; i <= index; i++)
|
||||||
|
{
|
||||||
|
newValues[i] = oldValues[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
newValues[index + 1] = Utilities.Utils.CloneValue(oldValues[index]);
|
||||||
|
|
||||||
|
for (int i = index + 1; i < count; i++)
|
||||||
|
{
|
||||||
|
newValues[i + 1] = oldValues[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
SetValue(newValues);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shifts the specified item at the given index and moves it through the list to the other item. It supports undo.
|
/// Shifts the specified item at the given index and moves it through the list to the other item. It supports undo.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ internal class UIControlRefPickerControl : FlaxObjectRefPickerControl
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override bool IsValid(Object obj)
|
protected override bool IsValid(Object obj)
|
||||||
{
|
{
|
||||||
return obj == null || (obj is UIControl control && control.Control.GetType() == ControlType);
|
return obj == null || (obj is UIControl control && ControlType.IsAssignableFrom(control.Control.GetType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using FlaxEditor.GUI;
|
using FlaxEditor.GUI;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
|
using FlaxEngine;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.CustomEditors.Editors
|
namespace FlaxEditor.CustomEditors.Editors
|
||||||
@@ -81,9 +82,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private OptionType[] _options;
|
private OptionType[] _options;
|
||||||
private ScriptType _type;
|
private ScriptType _type;
|
||||||
|
private Elements.PropertiesListElement _typeItem;
|
||||||
|
|
||||||
private ScriptType Type => Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
|
private ScriptType Type => Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool RevertValueWithChildren => false; // Always revert value for a whole object
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
@@ -98,7 +103,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
_type = type;
|
_type = type;
|
||||||
|
|
||||||
// Type
|
// Type
|
||||||
var typeEditor = layout.ComboBox(TypeComboBoxName, "Type of the object value. Use it to change the object.");
|
_typeItem = layout.AddPropertyItem(TypeComboBoxName, "Type of the object value. Use it to change the object.");
|
||||||
|
var typeEditor = _typeItem.ComboBox();
|
||||||
for (int i = 0; i < _options.Length; i++)
|
for (int i = 0; i < _options.Length; i++)
|
||||||
{
|
{
|
||||||
typeEditor.ComboBox.AddItem(_options[i].Name);
|
typeEditor.ComboBox.AddItem(_options[i].Name);
|
||||||
@@ -126,6 +132,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
// Value
|
// Value
|
||||||
var values = new CustomValueContainer(type, (instance, index) => instance);
|
var values = new CustomValueContainer(type, (instance, index) => instance);
|
||||||
|
if (Values.HasReferenceValue)
|
||||||
|
values.SetReferenceValue(Values.ReferenceValue);
|
||||||
values.AddRange(Values);
|
values.AddRange(Values);
|
||||||
var editor = CustomEditorsUtil.CreateEditor(type);
|
var editor = CustomEditorsUtil.CreateEditor(type);
|
||||||
var style = editor.Style;
|
var style = editor.Style;
|
||||||
@@ -170,6 +178,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
base.Refresh();
|
base.Refresh();
|
||||||
|
|
||||||
|
// Show prefab diff when reference value type is different
|
||||||
|
var color = Color.Transparent;
|
||||||
|
if (Values.HasReferenceValue && CanRevertReferenceValue && Values[0]?.GetType() != Values.ReferenceValue?.GetType())
|
||||||
|
color = FlaxEngine.GUI.Style.Current.BackgroundSelected;
|
||||||
|
_typeItem.Labels[0].HighlightStripColor = color;
|
||||||
|
|
||||||
// Check if type has been modified outside the editor (eg. from code)
|
// Check if type has been modified outside the editor (eg. from code)
|
||||||
if (Type != _type)
|
if (Type != _type)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ namespace FlaxEditor.CustomEditors.GUI
|
|||||||
public class PropertiesList : PanelWithMargins
|
public class PropertiesList : PanelWithMargins
|
||||||
{
|
{
|
||||||
// TODO: sync splitter for whole presenter
|
// TODO: sync splitter for whole presenter
|
||||||
|
|
||||||
|
private const float SplitterPadding = 15;
|
||||||
|
private const float EditorsMinWidthRatio = 0.4f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The splitter size (in pixels).
|
/// The splitter size (in pixels).
|
||||||
@@ -25,6 +28,7 @@ namespace FlaxEditor.CustomEditors.GUI
|
|||||||
private Rectangle _splitterRect;
|
private Rectangle _splitterRect;
|
||||||
private bool _splitterClicked, _mouseOverSplitter;
|
private bool _splitterClicked, _mouseOverSplitter;
|
||||||
private bool _cursorChanged;
|
private bool _cursorChanged;
|
||||||
|
private bool _hasCustomSplitterValue;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the splitter value (always in range [0; 1]).
|
/// Gets or sets the splitter value (always in range [0; 1]).
|
||||||
@@ -66,6 +70,26 @@ namespace FlaxEditor.CustomEditors.GUI
|
|||||||
UpdateSplitRect();
|
UpdateSplitRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AutoSizeSplitter()
|
||||||
|
{
|
||||||
|
if (_hasCustomSplitterValue || !Editor.Instance.Options.Options.Interface.AutoSizePropertiesPanelSplitter)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Font font = Style.Current.FontMedium;
|
||||||
|
|
||||||
|
float largestWidth = 0f;
|
||||||
|
for (int i = 0; i < _element.Labels.Count; i++)
|
||||||
|
{
|
||||||
|
Label currentLabel = _element.Labels[i];
|
||||||
|
Float2 dimensions = font.MeasureText(currentLabel.Text);
|
||||||
|
float width = dimensions.X + currentLabel.Margin.Left + SplitterPadding;
|
||||||
|
|
||||||
|
largestWidth = Mathf.Max(largestWidth, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
SplitterValue = Mathf.Clamp(largestWidth / Width, 0, 1 - EditorsMinWidthRatio);
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateSplitRect()
|
private void UpdateSplitRect()
|
||||||
{
|
{
|
||||||
_splitterRect = new Rectangle(Mathf.Clamp(_splitterValue * Width - SplitterSize * 0.5f, 0.0f, Width), 0, SplitterSize, Height);
|
_splitterRect = new Rectangle(Mathf.Clamp(_splitterValue * Width - SplitterSize * 0.5f, 0.0f, Width), 0, SplitterSize, Height);
|
||||||
@@ -122,6 +146,7 @@ namespace FlaxEditor.CustomEditors.GUI
|
|||||||
SplitterValue = location.X / Width;
|
SplitterValue = location.X / Width;
|
||||||
Cursor = CursorType.SizeWE;
|
Cursor = CursorType.SizeWE;
|
||||||
_cursorChanged = true;
|
_cursorChanged = true;
|
||||||
|
_hasCustomSplitterValue = true;
|
||||||
}
|
}
|
||||||
else if (_mouseOverSplitter)
|
else if (_mouseOverSplitter)
|
||||||
{
|
{
|
||||||
@@ -195,6 +220,7 @@ namespace FlaxEditor.CustomEditors.GUI
|
|||||||
// Refresh
|
// Refresh
|
||||||
UpdateSplitRect();
|
UpdateSplitRect();
|
||||||
PerformLayout(true);
|
PerformLayout(true);
|
||||||
|
AutoSizeSplitter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -268,8 +268,8 @@ bool Editor::CheckProjectUpgrade()
|
|||||||
// Check if last version was older
|
// Check if last version was older
|
||||||
else if (lastVersion.Major < FLAXENGINE_VERSION_MAJOR || (lastVersion.Major == FLAXENGINE_VERSION_MAJOR && lastVersion.Minor < FLAXENGINE_VERSION_MINOR))
|
else if (lastVersion.Major < FLAXENGINE_VERSION_MAJOR || (lastVersion.Major == FLAXENGINE_VERSION_MAJOR && lastVersion.Minor < FLAXENGINE_VERSION_MINOR))
|
||||||
{
|
{
|
||||||
LOG(Warning, "The project was opened with the older editor version last time");
|
LOG(Warning, "The project was last opened with an older editor version");
|
||||||
const auto result = MessageBox::Show(TEXT("The project was opened with the older editor version last time. Loading it may modify existing data so older editor version won't open it. Do you want to perform a backup before or cancel operation?"), TEXT("Project upgrade"), MessageBoxButtons::YesNoCancel, MessageBoxIcon::Question);
|
const auto result = MessageBox::Show(TEXT("The project was last opened with an older editor version.\nLoading it may modify existing data, which can result in older editor versions being unable to open it.\n\nDo you want to perform a backup before or cancel the operation?"), TEXT("Project upgrade"), MessageBoxButtons::YesNoCancel, MessageBoxIcon::Question);
|
||||||
if (result == DialogResult::Yes)
|
if (result == DialogResult::Yes)
|
||||||
{
|
{
|
||||||
if (BackupProject())
|
if (BackupProject())
|
||||||
@@ -291,8 +291,8 @@ bool Editor::CheckProjectUpgrade()
|
|||||||
// Check if last version was newer
|
// Check if last version was newer
|
||||||
else if (lastVersion.Major > FLAXENGINE_VERSION_MAJOR || (lastVersion.Major == FLAXENGINE_VERSION_MAJOR && lastVersion.Minor > FLAXENGINE_VERSION_MINOR))
|
else if (lastVersion.Major > FLAXENGINE_VERSION_MAJOR || (lastVersion.Major == FLAXENGINE_VERSION_MAJOR && lastVersion.Minor > FLAXENGINE_VERSION_MINOR))
|
||||||
{
|
{
|
||||||
LOG(Warning, "The project was opened with the newer editor version last time");
|
LOG(Warning, "The project was last opened with a newer editor version");
|
||||||
const auto result = MessageBox::Show(TEXT("The project was opened with the newer editor version last time. Loading it may fail and corrupt existing data. Do you want to perform a backup before or cancel operation?"), TEXT("Project upgrade"), MessageBoxButtons::YesNoCancel, MessageBoxIcon::Warning);
|
const auto result = MessageBox::Show(TEXT("The project was last opened with a newer editor version.\nLoading it may fail and corrupt existing data.\n\nDo you want to perform a backup before loading or cancel the operation?"), TEXT("Project upgrade"), MessageBoxButtons::YesNoCancel, MessageBoxIcon::Warning);
|
||||||
if (result == DialogResult::Yes)
|
if (result == DialogResult::Yes)
|
||||||
{
|
{
|
||||||
if (BackupProject())
|
if (BackupProject())
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ namespace FlaxEditor
|
|||||||
private readonly List<EditorModule> _modules = new List<EditorModule>(16);
|
private readonly List<EditorModule> _modules = new List<EditorModule>(16);
|
||||||
private bool _isAfterInit, _areModulesInited, _areModulesAfterInitEnd, _isHeadlessMode, _autoExit;
|
private bool _isAfterInit, _areModulesInited, _areModulesAfterInitEnd, _isHeadlessMode, _autoExit;
|
||||||
private string _projectToOpen;
|
private string _projectToOpen;
|
||||||
|
private bool _projectIsNew;
|
||||||
private float _lastAutoSaveTimer, _autoExitTimeout = 0.1f;
|
private float _lastAutoSaveTimer, _autoExitTimeout = 0.1f;
|
||||||
private Button _saveNowButton;
|
private Button _saveNowButton;
|
||||||
private Button _cancelSaveButton;
|
private Button _cancelSaveButton;
|
||||||
@@ -528,7 +529,11 @@ namespace FlaxEditor
|
|||||||
var timeSinceLastSave = Time.UnscaledGameTime - _lastAutoSaveTimer;
|
var timeSinceLastSave = Time.UnscaledGameTime - _lastAutoSaveTimer;
|
||||||
var timeToNextSave = options.AutoSaveFrequency * 60.0f - timeSinceLastSave;
|
var timeToNextSave = options.AutoSaveFrequency * 60.0f - timeSinceLastSave;
|
||||||
|
|
||||||
if (timeToNextSave <= 0.0f || _autoSaveNow)
|
if (timeToNextSave <= 0.0f && GetWindows().Any(x => x.GUI.Children.Any(c => c is GUI.ContextMenu.ContextMenuBase)))
|
||||||
|
{
|
||||||
|
// Skip aut-save if any context menu is opened to wait for user to end interaction
|
||||||
|
}
|
||||||
|
else if (timeToNextSave <= 0.0f || _autoSaveNow)
|
||||||
{
|
{
|
||||||
Log("Auto save");
|
Log("Auto save");
|
||||||
_lastAutoSaveTimer = Time.UnscaledGameTime;
|
_lastAutoSaveTimer = Time.UnscaledGameTime;
|
||||||
@@ -733,11 +738,12 @@ namespace FlaxEditor
|
|||||||
var procSettings = new CreateProcessSettings
|
var procSettings = new CreateProcessSettings
|
||||||
{
|
{
|
||||||
FileName = Platform.ExecutableFilePath,
|
FileName = Platform.ExecutableFilePath,
|
||||||
Arguments = string.Format("-project \"{0}\"", _projectToOpen),
|
Arguments = string.Format("-project \"{0}\"" + (_projectIsNew ? " -new" : string.Empty), _projectToOpen),
|
||||||
ShellExecute = true,
|
ShellExecute = true,
|
||||||
WaitForEnd = false,
|
WaitForEnd = false,
|
||||||
HiddenWindow = false,
|
HiddenWindow = false,
|
||||||
};
|
};
|
||||||
|
_projectIsNew = false;
|
||||||
_projectToOpen = null;
|
_projectToOpen = null;
|
||||||
Platform.CreateProcess(ref procSettings);
|
Platform.CreateProcess(ref procSettings);
|
||||||
}
|
}
|
||||||
@@ -786,6 +792,24 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the given project. Afterwards closes this project with running editor and opens the given project.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="projectFilePath">The project file path.</param>
|
||||||
|
public void NewProject(string projectFilePath)
|
||||||
|
{
|
||||||
|
if (projectFilePath == null)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Missing project");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache project path and start editor exit (it will open new instance on valid closing)
|
||||||
|
_projectToOpen = StringUtils.NormalizePath(Path.GetDirectoryName(projectFilePath));
|
||||||
|
_projectIsNew = true;
|
||||||
|
Windows.MainWindow.Close(ClosingReason.User);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes this project with running editor and opens the given project.
|
/// Closes this project with running editor and opens the given project.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace FlaxEditor
|
|||||||
public SpriteHandle Globe32;
|
public SpriteHandle Globe32;
|
||||||
public SpriteHandle CamSpeed32;
|
public SpriteHandle CamSpeed32;
|
||||||
public SpriteHandle Link32;
|
public SpriteHandle Link32;
|
||||||
|
public SpriteHandle BrokenLink32;
|
||||||
public SpriteHandle Add32;
|
public SpriteHandle Add32;
|
||||||
public SpriteHandle Left32;
|
public SpriteHandle Left32;
|
||||||
public SpriteHandle Right32;
|
public SpriteHandle Right32;
|
||||||
@@ -94,6 +95,7 @@ namespace FlaxEditor
|
|||||||
public SpriteHandle Search64;
|
public SpriteHandle Search64;
|
||||||
public SpriteHandle Bone64;
|
public SpriteHandle Bone64;
|
||||||
public SpriteHandle Link64;
|
public SpriteHandle Link64;
|
||||||
|
public SpriteHandle BrokenLink64;
|
||||||
public SpriteHandle Build64;
|
public SpriteHandle Build64;
|
||||||
public SpriteHandle Add64;
|
public SpriteHandle Add64;
|
||||||
public SpriteHandle ShipIt64;
|
public SpriteHandle ShipIt64;
|
||||||
|
|||||||
@@ -117,9 +117,10 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
public ContextMenuBase()
|
public ContextMenuBase()
|
||||||
: base(0, 0, 120, 32)
|
: base(0, 0, 120, 32)
|
||||||
{
|
{
|
||||||
_direction = ContextMenuDirection.RightDown;
|
|
||||||
Visible = false;
|
Visible = false;
|
||||||
|
AutoFocus = true;
|
||||||
|
|
||||||
|
_direction = ContextMenuDirection.RightDown;
|
||||||
_isSubMenu = true;
|
_isSubMenu = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
public ColorSelector(float wheelSize)
|
public ColorSelector(float wheelSize)
|
||||||
: base(0, 0, wheelSize, wheelSize)
|
: base(0, 0, wheelSize, wheelSize)
|
||||||
{
|
{
|
||||||
|
AutoFocus = true;
|
||||||
|
|
||||||
_colorWheelSprite = Editor.Instance.Icons.ColorWheel128;
|
_colorWheelSprite = Editor.Instance.Icons.ColorWheel128;
|
||||||
_wheelRect = new Rectangle(0, 0, wheelSize, wheelSize);
|
_wheelRect = new Rectangle(0, 0, wheelSize, wheelSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using FlaxEditor.GUI.ContextMenu;
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
|
using FlaxEditor.Options;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
@@ -13,12 +14,12 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
public class DockPanelProxy : ContainerControl
|
public class DockPanelProxy : ContainerControl
|
||||||
{
|
{
|
||||||
private DockPanel _panel;
|
private DockPanel _panel;
|
||||||
|
private InterfaceOptions.TabCloseButtonVisibility closeButtonVisibility;
|
||||||
private double _dragEnterTime = -1;
|
private double _dragEnterTime = -1;
|
||||||
#if PLATFORM_WINDOWS
|
private float _tabHeight = Editor.Instance.Options.Options.Interface.TabHeight;
|
||||||
private const bool HideTabForSingleTab = true;
|
private bool _useMinimumTabWidth = Editor.Instance.Options.Options.Interface.UseMinimumTabWidth;
|
||||||
#else
|
private float _minimumTabWidth = Editor.Instance.Options.Options.Interface.MinimumTabWidth;
|
||||||
private const bool HideTabForSingleTab = false;
|
private readonly bool _hideTabForSingleTab = Utilities.Utils.HideSingleTabWindowTabBars();
|
||||||
#endif
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The is mouse down flag (left button).
|
/// The is mouse down flag (left button).
|
||||||
@@ -60,8 +61,8 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DockWindow StartDragAsyncWindow;
|
public DockWindow StartDragAsyncWindow;
|
||||||
|
|
||||||
private Rectangle HeaderRectangle => new Rectangle(0, 0, Width, DockPanel.DefaultHeaderHeight);
|
private Rectangle HeaderRectangle => new Rectangle(0, 0, Width, _tabHeight);
|
||||||
private bool IsSingleFloatingWindow => HideTabForSingleTab && _panel.TabsCount == 1 && _panel.IsFloating && _panel.ChildPanelsCount == 0;
|
private bool IsSingleFloatingWindow => _hideTabForSingleTab && _panel.TabsCount == 1 && _panel.IsFloating && _panel.ChildPanelsCount == 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="DockPanelProxy"/> class.
|
/// Initializes a new instance of the <see cref="DockPanelProxy"/> class.
|
||||||
@@ -70,11 +71,17 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
internal DockPanelProxy(DockPanel panel)
|
internal DockPanelProxy(DockPanel panel)
|
||||||
: base(0, 0, 64, 64)
|
: base(0, 0, 64, 64)
|
||||||
{
|
{
|
||||||
AutoFocus = false;
|
|
||||||
|
|
||||||
_panel = panel;
|
_panel = panel;
|
||||||
AnchorPreset = AnchorPresets.StretchAll;
|
AnchorPreset = AnchorPresets.StretchAll;
|
||||||
Offsets = Margin.Zero;
|
Offsets = Margin.Zero;
|
||||||
|
|
||||||
|
Editor.Instance.Options.OptionsChanged += OnEditorOptionsChanged;
|
||||||
|
OnEditorOptionsChanged(Editor.Instance.Options.Options);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEditorOptionsChanged(EditorOptions options)
|
||||||
|
{
|
||||||
|
closeButtonVisibility = options.Interface.ShowTabCloseButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DockWindow GetTabAtPos(Float2 position, out bool closeButton)
|
private DockWindow GetTabAtPos(Float2 position, out bool closeButton)
|
||||||
@@ -85,11 +92,11 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
var tabsCount = _panel.TabsCount;
|
var tabsCount = _panel.TabsCount;
|
||||||
if (tabsCount == 1)
|
if (tabsCount == 1)
|
||||||
{
|
{
|
||||||
var crossRect = new Rectangle(Width - DockPanel.DefaultButtonsSize - DockPanel.DefaultButtonsMargin, (DockPanel.DefaultHeaderHeight - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize);
|
var crossRect = new Rectangle(Width - DockPanel.DefaultButtonsSize - DockPanel.DefaultButtonsMargin, (HeaderRectangle.Height - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize);
|
||||||
if (HeaderRectangle.Contains(position))
|
if (HeaderRectangle.Contains(position))
|
||||||
{
|
{
|
||||||
closeButton = crossRect.Contains(position);
|
|
||||||
result = _panel.GetTab(0);
|
result = _panel.GetTab(0);
|
||||||
|
closeButton = crossRect.Contains(position) && IsCloseButtonVisible(result, closeButtonVisibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -98,15 +105,17 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
for (int i = 0; i < tabsCount; i++)
|
for (int i = 0; i < tabsCount; i++)
|
||||||
{
|
{
|
||||||
var tab = _panel.GetTab(i);
|
var tab = _panel.GetTab(i);
|
||||||
var titleSize = tab.TitleSize;
|
float width = CalculateTabWidth(tab, closeButtonVisibility);
|
||||||
var iconWidth = tab.Icon.IsValid ? DockPanel.DefaultButtonsSize + DockPanel.DefaultLeftTextMargin : 0;
|
|
||||||
var width = titleSize.X + DockPanel.DefaultButtonsSize + 2 * DockPanel.DefaultButtonsMargin + DockPanel.DefaultLeftTextMargin + DockPanel.DefaultRightTextMargin + iconWidth;
|
if (_useMinimumTabWidth && width < _minimumTabWidth)
|
||||||
var tabRect = new Rectangle(x, 0, width, DockPanel.DefaultHeaderHeight);
|
width = _minimumTabWidth;
|
||||||
|
|
||||||
|
var tabRect = new Rectangle(x, 0, width, HeaderRectangle.Height);
|
||||||
var isMouseOver = tabRect.Contains(position);
|
var isMouseOver = tabRect.Contains(position);
|
||||||
if (isMouseOver)
|
if (isMouseOver)
|
||||||
{
|
{
|
||||||
var crossRect = new Rectangle(x + width - DockPanel.DefaultButtonsSize - DockPanel.DefaultButtonsMargin, (DockPanel.DefaultHeaderHeight - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize);
|
var crossRect = new Rectangle(x + width - DockPanel.DefaultButtonsSize - DockPanel.DefaultButtonsMargin, (HeaderRectangle.Height - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize);
|
||||||
closeButton = crossRect.Contains(position);
|
closeButton = crossRect.Contains(position) && IsCloseButtonVisible(tab, closeButtonVisibility);
|
||||||
result = tab;
|
result = tab;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -117,6 +126,24 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsCloseButtonVisible(DockWindow win, InterfaceOptions.TabCloseButtonVisibility visibilityMode)
|
||||||
|
{
|
||||||
|
return visibilityMode != InterfaceOptions.TabCloseButtonVisibility.Never &&
|
||||||
|
(visibilityMode == InterfaceOptions.TabCloseButtonVisibility.Always ||
|
||||||
|
(visibilityMode == InterfaceOptions.TabCloseButtonVisibility.SelectedTab && _panel.SelectedTab == win));
|
||||||
|
}
|
||||||
|
|
||||||
|
private float CalculateTabWidth(DockWindow win, InterfaceOptions.TabCloseButtonVisibility visibilityMode)
|
||||||
|
{
|
||||||
|
var iconWidth = win.Icon.IsValid ? DockPanel.DefaultButtonsSize + DockPanel.DefaultLeftTextMargin : 0;
|
||||||
|
var width = win.TitleSize.X + DockPanel.DefaultLeftTextMargin + DockPanel.DefaultRightTextMargin + iconWidth;
|
||||||
|
|
||||||
|
if (IsCloseButtonVisible(win, visibilityMode))
|
||||||
|
width += 2 * DockPanel.DefaultButtonsMargin + DockPanel.DefaultButtonsSize;
|
||||||
|
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
private void GetTabRect(DockWindow win, out Rectangle bounds)
|
private void GetTabRect(DockWindow win, out Rectangle bounds)
|
||||||
{
|
{
|
||||||
FlaxEngine.Assertions.Assert.IsTrue(_panel.ContainsTab(win));
|
FlaxEngine.Assertions.Assert.IsTrue(_panel.ContainsTab(win));
|
||||||
@@ -134,10 +161,10 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
var tab = _panel.GetTab(i);
|
var tab = _panel.GetTab(i);
|
||||||
var titleSize = tab.TitleSize;
|
var titleSize = tab.TitleSize;
|
||||||
float width = titleSize.X + DockPanel.DefaultButtonsSize + 2 * DockPanel.DefaultButtonsMargin + DockPanel.DefaultLeftTextMargin + DockPanel.DefaultRightTextMargin;
|
float width = CalculateTabWidth(tab, closeButtonVisibility);
|
||||||
if (tab == win)
|
if (tab == win)
|
||||||
{
|
{
|
||||||
bounds = new Rectangle(x, 0, width, DockPanel.DefaultHeaderHeight);
|
bounds = new Rectangle(x, 0, width, HeaderRectangle.Height);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
x += width;
|
x += width;
|
||||||
@@ -217,7 +244,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
Render2D.DrawSprite(
|
Render2D.DrawSprite(
|
||||||
tab.Icon,
|
tab.Icon,
|
||||||
new Rectangle(DockPanel.DefaultLeftTextMargin, (DockPanel.DefaultHeaderHeight - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize),
|
new Rectangle(DockPanel.DefaultLeftTextMargin, (HeaderRectangle.Height - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize),
|
||||||
style.Foreground);
|
style.Foreground);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -226,17 +253,20 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
Render2D.DrawText(
|
Render2D.DrawText(
|
||||||
style.FontMedium,
|
style.FontMedium,
|
||||||
tab.Title,
|
tab.Title,
|
||||||
new Rectangle(DockPanel.DefaultLeftTextMargin + iconWidth, 0, Width - DockPanel.DefaultLeftTextMargin - DockPanel.DefaultButtonsSize - 2 * DockPanel.DefaultButtonsMargin, DockPanel.DefaultHeaderHeight),
|
new Rectangle(DockPanel.DefaultLeftTextMargin + iconWidth, 0, Width - DockPanel.DefaultLeftTextMargin - DockPanel.DefaultButtonsSize - 2 * DockPanel.DefaultButtonsMargin, HeaderRectangle.Height),
|
||||||
style.Foreground,
|
style.Foreground,
|
||||||
TextAlignment.Near,
|
TextAlignment.Near,
|
||||||
TextAlignment.Center);
|
TextAlignment.Center);
|
||||||
|
|
||||||
// Draw cross
|
if (IsCloseButtonVisible(tab, closeButtonVisibility))
|
||||||
var crossRect = new Rectangle(Width - DockPanel.DefaultButtonsSize - DockPanel.DefaultButtonsMargin, (DockPanel.DefaultHeaderHeight - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize);
|
{
|
||||||
bool isMouseOverCross = isMouseOver && crossRect.Contains(MousePosition);
|
// Draw cross
|
||||||
if (isMouseOverCross)
|
var crossRect = new Rectangle(Width - DockPanel.DefaultButtonsSize - DockPanel.DefaultButtonsMargin, (HeaderRectangle.Height - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize);
|
||||||
Render2D.FillRectangle(crossRect, (containsFocus ? style.BackgroundSelected : style.LightBackground) * 1.3f);
|
bool isMouseOverCross = isMouseOver && crossRect.Contains(MousePosition);
|
||||||
Render2D.DrawSprite(style.Cross, crossRect, isMouseOverCross ? style.Foreground : style.ForegroundGrey);
|
if (isMouseOverCross)
|
||||||
|
Render2D.FillRectangle(crossRect, (containsFocus ? style.BackgroundSelected : style.LightBackground) * 1.3f);
|
||||||
|
Render2D.DrawSprite(style.Cross, crossRect, isMouseOverCross ? style.Foreground : style.ForegroundGrey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -250,10 +280,14 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
// Cache data
|
// Cache data
|
||||||
var tab = _panel.GetTab(i);
|
var tab = _panel.GetTab(i);
|
||||||
var tabColor = Color.Black;
|
var tabColor = Color.Black;
|
||||||
var titleSize = tab.TitleSize;
|
|
||||||
var iconWidth = tab.Icon.IsValid ? DockPanel.DefaultButtonsSize + DockPanel.DefaultLeftTextMargin : 0;
|
var iconWidth = tab.Icon.IsValid ? DockPanel.DefaultButtonsSize + DockPanel.DefaultLeftTextMargin : 0;
|
||||||
var width = titleSize.X + DockPanel.DefaultButtonsSize + 2 * DockPanel.DefaultButtonsMargin + DockPanel.DefaultLeftTextMargin + DockPanel.DefaultRightTextMargin + iconWidth;
|
|
||||||
var tabRect = new Rectangle(x, 0, width, DockPanel.DefaultHeaderHeight);
|
float width = CalculateTabWidth(tab, closeButtonVisibility);
|
||||||
|
|
||||||
|
if (_useMinimumTabWidth && width < _minimumTabWidth)
|
||||||
|
width = _minimumTabWidth;
|
||||||
|
|
||||||
|
var tabRect = new Rectangle(x, 0, width, headerRect.Height);
|
||||||
var isMouseOver = tabRect.Contains(MousePosition);
|
var isMouseOver = tabRect.Contains(MousePosition);
|
||||||
var isSelected = _panel.SelectedTab == tab;
|
var isSelected = _panel.SelectedTab == tab;
|
||||||
|
|
||||||
@@ -280,7 +314,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
Render2D.DrawSprite(
|
Render2D.DrawSprite(
|
||||||
tab.Icon,
|
tab.Icon,
|
||||||
new Rectangle(x + DockPanel.DefaultLeftTextMargin, (DockPanel.DefaultHeaderHeight - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize),
|
new Rectangle(x + DockPanel.DefaultLeftTextMargin, (HeaderRectangle.Height - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize),
|
||||||
style.Foreground);
|
style.Foreground);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -289,27 +323,27 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
Render2D.DrawText(
|
Render2D.DrawText(
|
||||||
style.FontMedium,
|
style.FontMedium,
|
||||||
tab.Title,
|
tab.Title,
|
||||||
new Rectangle(x + DockPanel.DefaultLeftTextMargin + iconWidth, 0, 10000, DockPanel.DefaultHeaderHeight),
|
new Rectangle(x + DockPanel.DefaultLeftTextMargin + iconWidth, 0, 10000, HeaderRectangle.Height),
|
||||||
style.Foreground,
|
style.Foreground,
|
||||||
TextAlignment.Near,
|
TextAlignment.Near,
|
||||||
TextAlignment.Center);
|
TextAlignment.Center);
|
||||||
|
|
||||||
// Draw cross
|
// Draw cross
|
||||||
if (isSelected || isMouseOver)
|
if (IsCloseButtonVisible(tab, closeButtonVisibility))
|
||||||
{
|
{
|
||||||
var crossRect = new Rectangle(x + width - DockPanel.DefaultButtonsSize - DockPanel.DefaultButtonsMargin, (DockPanel.DefaultHeaderHeight - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize);
|
var crossRect = new Rectangle(x + width - DockPanel.DefaultButtonsSize - DockPanel.DefaultButtonsMargin, (HeaderRectangle.Height - DockPanel.DefaultButtonsSize) / 2, DockPanel.DefaultButtonsSize, DockPanel.DefaultButtonsSize);
|
||||||
bool isMouseOverCross = isMouseOver && crossRect.Contains(MousePosition);
|
bool isMouseOverCross = isMouseOver && crossRect.Contains(MousePosition);
|
||||||
if (isMouseOverCross)
|
if (isMouseOverCross)
|
||||||
Render2D.FillRectangle(crossRect, tabColor * 1.3f);
|
Render2D.FillRectangle(crossRect, tabColor * 1.3f);
|
||||||
Render2D.DrawSprite(style.Cross, crossRect, isMouseOverCross ? style.Foreground : style.ForegroundGrey);
|
Render2D.DrawSprite(style.Cross, crossRect, isMouseOverCross ? style.Foreground : style.ForegroundGrey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move
|
// Set the start position for the next tab
|
||||||
x += width;
|
x += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw selected tab strip
|
// Draw selected tab strip
|
||||||
Render2D.FillRectangle(new Rectangle(0, DockPanel.DefaultHeaderHeight - 2, Width, 2), containsFocus ? style.BackgroundSelected : style.BackgroundNormal);
|
Render2D.FillRectangle(new Rectangle(0, HeaderRectangle.Height - 2, Width, 2), containsFocus ? style.BackgroundSelected : style.BackgroundNormal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,7 +576,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
if (IsSingleFloatingWindow)
|
if (IsSingleFloatingWindow)
|
||||||
rect = new Rectangle(0, 0, Width, Height);
|
rect = new Rectangle(0, 0, Width, Height);
|
||||||
else
|
else
|
||||||
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
|
rect = new Rectangle(0, HeaderRectangle.Height, Width, Height - HeaderRectangle.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DragDropEffect TrySelectTabUnderLocation(ref Float2 location)
|
private DragDropEffect TrySelectTabUnderLocation(ref Float2 location)
|
||||||
|
|||||||
@@ -129,11 +129,39 @@ namespace FlaxEditor.GUI.Input
|
|||||||
{
|
{
|
||||||
base.Draw();
|
base.Draw();
|
||||||
|
|
||||||
var style = Style.Current;
|
bool isTransparent = _value.A < 1;
|
||||||
var r = new Rectangle(0, 0, Width, Height);
|
|
||||||
|
|
||||||
Render2D.FillRectangle(r, _value);
|
var style = Style.Current;
|
||||||
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
|
var fullRect = new Rectangle(0, 0, Width, Height);
|
||||||
|
var colorRect = new Rectangle(0, 0, isTransparent ? Width * 0.7f : Width, Height);
|
||||||
|
|
||||||
|
if (isTransparent)
|
||||||
|
{
|
||||||
|
var alphaRect = new Rectangle(colorRect.Right, 0, Width - colorRect.Right, Height);
|
||||||
|
|
||||||
|
// Draw checkerboard pattern to part of the color value box
|
||||||
|
Render2D.FillRectangle(alphaRect, Color.White);
|
||||||
|
var smallRectSize = 7.9f;
|
||||||
|
var numHor = Mathf.CeilToInt(alphaRect.Width / smallRectSize);
|
||||||
|
var numVer = Mathf.CeilToInt(alphaRect.Height / smallRectSize);
|
||||||
|
for (int i = 0; i < numHor; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < numVer; j++)
|
||||||
|
{
|
||||||
|
if ((i + j) % 2 == 0)
|
||||||
|
{
|
||||||
|
var rect = new Rectangle(alphaRect.X + smallRectSize * i, alphaRect.Y + smallRectSize * j, new Float2(smallRectSize));
|
||||||
|
Render2D.PushClip(alphaRect);
|
||||||
|
Render2D.FillRectangle(rect, Color.Gray);
|
||||||
|
Render2D.PopClip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Render2D.FillRectangle(alphaRect, _value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Render2D.FillRectangle(colorRect, _value with { A = 1 });
|
||||||
|
Render2D.DrawRectangle(fullRect, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -368,6 +368,8 @@ namespace FlaxEditor.GUI.Input
|
|||||||
public SliderControl(float value, float x = 0, float y = 0, float width = 120, float min = float.MinValue, float max = float.MaxValue)
|
public SliderControl(float value, float x = 0, float y = 0, float width = 120, float min = float.MinValue, float max = float.MaxValue)
|
||||||
: base(x, y, width, TextBox.DefaultHeight)
|
: base(x, y, width, TextBox.DefaultHeight)
|
||||||
{
|
{
|
||||||
|
AutoFocus = true;
|
||||||
|
|
||||||
_min = min;
|
_min = min;
|
||||||
_max = max;
|
_max = max;
|
||||||
_value = Mathf.Clamp(value, min, max);
|
_value = Mathf.Clamp(value, min, max);
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ namespace FlaxEditor.GUI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public float SortScore;
|
public float SortScore;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wether the query highlights should be draw.
|
||||||
|
/// </summary>
|
||||||
|
public bool DrawHighlights = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when items gets clicked by the user.
|
/// Occurs when items gets clicked by the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -165,7 +170,7 @@ namespace FlaxEditor.GUI
|
|||||||
Render2D.FillRectangle(new Rectangle(Float2.Zero, Size), style.BackgroundHighlighted);
|
Render2D.FillRectangle(new Rectangle(Float2.Zero, Size), style.BackgroundHighlighted);
|
||||||
|
|
||||||
// Draw all highlights
|
// Draw all highlights
|
||||||
if (_highlights != null)
|
if (DrawHighlights && _highlights != null)
|
||||||
{
|
{
|
||||||
var color = style.ProgressNormal * 0.6f;
|
var color = style.ProgressNormal * 0.6f;
|
||||||
for (int i = 0; i < _highlights.Count; i++)
|
for (int i = 0; i < _highlights.Count; i++)
|
||||||
@@ -514,20 +519,15 @@ namespace FlaxEditor.GUI
|
|||||||
var items = ItemsPanel.Children;
|
var items = ItemsPanel.Children;
|
||||||
for (int i = 0; i < items.Count; i++)
|
for (int i = 0; i < items.Count; i++)
|
||||||
{
|
{
|
||||||
if (items[i] is Item item && item.Visible)
|
var currentItem = items[i];
|
||||||
|
if (currentItem is Item item && item.Visible)
|
||||||
result.Add(item);
|
result.Add(item);
|
||||||
}
|
else if (currentItem is DropPanel category && (!ignoreFoldedCategories || !category.IsClosed) && currentItem.Visible)
|
||||||
if (_categoryPanels != null)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < _categoryPanels.Count; i++)
|
|
||||||
{
|
{
|
||||||
var category = _categoryPanels[i];
|
|
||||||
if (!category.Visible || (ignoreFoldedCategories && category is DropPanel panel && panel.IsClosed))
|
|
||||||
continue;
|
|
||||||
for (int j = 0; j < category.Children.Count; j++)
|
for (int j = 0; j < category.Children.Count; j++)
|
||||||
{
|
{
|
||||||
if (category.Children[j] is Item item2 && item2.Visible)
|
if (category.Children[j] is Item categoryItem && categoryItem.Visible)
|
||||||
result.Add(item2);
|
result.Add(categoryItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -591,10 +591,6 @@ namespace FlaxEditor.GUI
|
|||||||
var items = GetVisibleItems(!controlDown);
|
var items = GetVisibleItems(!controlDown);
|
||||||
var focusedIndex = items.IndexOf(focusedItem);
|
var focusedIndex = items.IndexOf(focusedItem);
|
||||||
|
|
||||||
// If the user hasn't selected anything yet and is holding control, focus first folded item
|
|
||||||
if (focusedIndex == -1 && controlDown)
|
|
||||||
focusedIndex = GetVisibleItems(true).Count - 1;
|
|
||||||
|
|
||||||
int delta = key == KeyboardKeys.ArrowDown ? -1 : 1;
|
int delta = key == KeyboardKeys.ArrowDown ? -1 : 1;
|
||||||
int nextIndex = Mathf.Wrap(focusedIndex - delta, 0, items.Count - 1);
|
int nextIndex = Mathf.Wrap(focusedIndex - delta, 0, items.Count - 1);
|
||||||
var nextItem = items[nextIndex];
|
var nextItem = items[nextIndex];
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ namespace FlaxEditor.GUI
|
|||||||
/// <seealso cref="FlaxEngine.GUI.Panel" />
|
/// <seealso cref="FlaxEngine.GUI.Panel" />
|
||||||
public class NavigationBar : Panel
|
public class NavigationBar : Panel
|
||||||
{
|
{
|
||||||
|
private float _toolstripHeight = 0;
|
||||||
|
private Margin _toolstripMargin;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default buttons margin.
|
/// The default buttons margin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -50,9 +53,42 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
if (toolstrip == null)
|
if (toolstrip == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_toolstripHeight <= 0.0f)
|
||||||
|
{
|
||||||
|
// Cache initial toolstrip state
|
||||||
|
_toolstripHeight = toolstrip.Height;
|
||||||
|
_toolstripMargin = toolstrip.ItemsMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Control toolstrip bottom margin to prevent navigation bar scroll going over the buttons
|
||||||
|
var toolstripLocked = toolstrip.IsLayoutLocked;
|
||||||
|
toolstrip.IsLayoutLocked = true;
|
||||||
|
var toolstripHeight = _toolstripHeight;
|
||||||
|
var toolstripMargin = _toolstripMargin;
|
||||||
|
if (HScrollBar.Visible)
|
||||||
|
{
|
||||||
|
float scrollMargin = 8;
|
||||||
|
toolstripHeight += scrollMargin;
|
||||||
|
toolstripMargin.Bottom += scrollMargin;
|
||||||
|
}
|
||||||
|
toolstrip.Height = toolstripHeight;
|
||||||
|
toolstrip.IsLayoutLocked = toolstripLocked;
|
||||||
|
toolstrip.ItemsMargin = toolstripMargin;
|
||||||
|
|
||||||
var lastToolstripButton = toolstrip.LastButton;
|
var lastToolstripButton = toolstrip.LastButton;
|
||||||
var parentSize = Parent.Size;
|
var parentSize = Parent.Size;
|
||||||
Bounds = new Rectangle(lastToolstripButton.Right + 8.0f, 0, parentSize.X - X - 8.0f, toolstrip.Height);
|
Bounds = new Rectangle(lastToolstripButton.Right + 8.0f, 0, parentSize.X - X - 8.0f, toolstrip.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void PerformLayout(bool force = false)
|
||||||
|
{
|
||||||
|
base.PerformLayout(force);
|
||||||
|
|
||||||
|
// Stretch excluding toolstrip margin to fill the space
|
||||||
|
if (Parent is ToolStrip toolStrip)
|
||||||
|
Height = toolStrip.Height;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,10 @@ namespace FlaxEditor.GUI
|
|||||||
/// <returns>Created popup.</returns>
|
/// <returns>Created popup.</returns>
|
||||||
public static RenamePopup Show(Control control, Rectangle area, string value, bool isMultiline)
|
public static RenamePopup Show(Control control, Rectangle area, string value, bool isMultiline)
|
||||||
{
|
{
|
||||||
|
// hardcoded flushing layout for tree controls
|
||||||
|
if (control is Tree.TreeNode treeNode && treeNode.ParentTree != null)
|
||||||
|
treeNode.ParentTree.FlushPendingPerformLayout();
|
||||||
|
|
||||||
// Calculate the control size in the window space to handle scaled controls
|
// Calculate the control size in the window space to handle scaled controls
|
||||||
var upperLeft = control.PointToWindow(area.UpperLeft);
|
var upperLeft = control.PointToWindow(area.UpperLeft);
|
||||||
var bottomRight = control.PointToWindow(area.BottomRight);
|
var bottomRight = control.PointToWindow(area.BottomRight);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using System.Text;
|
|||||||
using FlaxEditor.GUI.Timeline.Undo;
|
using FlaxEditor.GUI.Timeline.Undo;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
using FlaxEngine.Json;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.GUI.Timeline.Tracks
|
namespace FlaxEditor.GUI.Timeline.Tracks
|
||||||
@@ -54,7 +55,10 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
var paramTypeName = LoadName(stream);
|
var paramTypeName = LoadName(stream);
|
||||||
e.EventParamsTypes[i] = TypeUtils.GetManagedType(paramTypeName);
|
e.EventParamsTypes[i] = TypeUtils.GetManagedType(paramTypeName);
|
||||||
if (e.EventParamsTypes[i] == null)
|
if (e.EventParamsTypes[i] == null)
|
||||||
|
{
|
||||||
|
Editor.LogError($"Unknown type {paramTypeName}.");
|
||||||
isInvalid = true;
|
isInvalid = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isInvalid)
|
if (isInvalid)
|
||||||
@@ -82,7 +86,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
for (int j = 0; j < paramsCount; j++)
|
for (int j = 0; j < paramsCount; j++)
|
||||||
{
|
{
|
||||||
stream.Read(dataBuffer, 0, e.EventParamsSizes[j]);
|
stream.Read(dataBuffer, 0, e.EventParamsSizes[j]);
|
||||||
key.Parameters[j] = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), e.EventParamsTypes[j]);
|
key.Parameters[j] = Utilities.Utils.ByteArrayToStructure(handle.AddrOfPinnedObject(), e.EventParamsTypes[j], e.EventParamsSizes[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
events[i] = new KeyframesEditor.Keyframe
|
events[i] = new KeyframesEditor.Keyframe
|
||||||
@@ -125,8 +129,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
|
|
||||||
for (int j = 0; j < paramsCount; j++)
|
for (int j = 0; j < paramsCount; j++)
|
||||||
{
|
{
|
||||||
Marshal.StructureToPtr(key.Parameters[j], ptr, true);
|
Utilities.Utils.StructureToByteArray(key.Parameters[j], e.EventParamsSizes[j], ptr, dataBuffer);
|
||||||
Marshal.Copy(ptr, dataBuffer, 0, e.EventParamsSizes[j]);
|
|
||||||
stream.Write(dataBuffer, 0, e.EventParamsSizes[j]);
|
stream.Write(dataBuffer, 0, e.EventParamsSizes[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +156,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The event key data.
|
/// The event key data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct EventKey
|
public struct EventKey : ICloneable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The parameters values.
|
/// The parameters values.
|
||||||
@@ -178,6 +181,26 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
sb.Append(')');
|
sb.Append(')');
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
if (Parameters == null)
|
||||||
|
return new EventKey();
|
||||||
|
|
||||||
|
// Deep clone parameter values (especially boxed value types need to be duplicated to avoid referencing the same ones)
|
||||||
|
var parameters = new object[Parameters.Length];
|
||||||
|
for (int i = 0; i < parameters.Length; i++)
|
||||||
|
{
|
||||||
|
var p = Parameters[i];
|
||||||
|
if (p == null || p is FlaxEngine.Object)
|
||||||
|
parameters[i] = Parameters[i];
|
||||||
|
else
|
||||||
|
parameters[i] = JsonSerializer.Deserialize(JsonSerializer.Serialize(p), p.GetType());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EventKey { Parameters = parameters };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -234,6 +257,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
var time = Timeline.CurrentTime;
|
var time = Timeline.CurrentTime;
|
||||||
if (!TryGetValue(out var value))
|
if (!TryGetValue(out var value))
|
||||||
value = Events.Evaluate(time);
|
value = Events.Evaluate(time);
|
||||||
|
value = ((ICloneable)value).Clone();
|
||||||
|
|
||||||
// Find event at the current location
|
// Find event at the current location
|
||||||
for (int i = Events.Keyframes.Count - 1; i >= 0; i--)
|
for (int i = Events.Keyframes.Count - 1; i >= 0; i--)
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
{
|
{
|
||||||
var time = stream.ReadSingle();
|
var time = stream.ReadSingle();
|
||||||
stream.Read(dataBuffer, 0, e.ValueSize);
|
stream.Read(dataBuffer, 0, e.ValueSize);
|
||||||
var value = Marshal.PtrToStructure(handle.AddrOfPinnedObject(), propertyType);
|
var value = Utilities.Utils.ByteArrayToStructure(handle.AddrOfPinnedObject(), propertyType, e.ValueSize);
|
||||||
|
|
||||||
keyframes[i] = new KeyframesEditor.Keyframe
|
keyframes[i] = new KeyframesEditor.Keyframe
|
||||||
{
|
{
|
||||||
@@ -142,8 +142,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
for (int i = 0; i < keyframes.Count; i++)
|
for (int i = 0; i < keyframes.Count; i++)
|
||||||
{
|
{
|
||||||
var keyframe = keyframes[i];
|
var keyframe = keyframes[i];
|
||||||
Marshal.StructureToPtr(keyframe.Value, ptr, true);
|
Utilities.Utils.StructureToByteArray(keyframe.Value, e.ValueSize, ptr, dataBuffer);
|
||||||
Marshal.Copy(ptr, dataBuffer, 0, e.ValueSize);
|
|
||||||
stream.Write(keyframe.Time);
|
stream.Write(keyframe.Time);
|
||||||
stream.Write(dataBuffer);
|
stream.Write(dataBuffer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,15 +13,7 @@ namespace FlaxEditor.GUI
|
|||||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||||
public class ToolStrip : ContainerControl
|
public class ToolStrip : ContainerControl
|
||||||
{
|
{
|
||||||
/// <summary>
|
private Margin _itemsMargin;
|
||||||
/// The default margin vertically.
|
|
||||||
/// </summary>
|
|
||||||
public const int DefaultMarginV = 1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The default margin horizontally.
|
|
||||||
/// </summary>
|
|
||||||
public const int DefaultMarginH = 2;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event fired when button gets clicked with the primary mouse button.
|
/// Event fired when button gets clicked with the primary mouse button.
|
||||||
@@ -66,10 +58,26 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the space around items.
|
||||||
|
/// </summary>
|
||||||
|
public Margin ItemsMargin
|
||||||
|
{
|
||||||
|
get => _itemsMargin;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_itemsMargin != value)
|
||||||
|
{
|
||||||
|
_itemsMargin = value;
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the height for the items.
|
/// Gets the height for the items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float ItemsHeight => Height - 2 * DefaultMarginV;
|
public float ItemsHeight => Height - _itemsMargin.Height;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ToolStrip"/> class.
|
/// Initializes a new instance of the <see cref="ToolStrip"/> class.
|
||||||
@@ -82,6 +90,7 @@ namespace FlaxEditor.GUI
|
|||||||
AnchorPreset = AnchorPresets.HorizontalStretchTop;
|
AnchorPreset = AnchorPresets.HorizontalStretchTop;
|
||||||
BackgroundColor = Style.Current.LightBackground;
|
BackgroundColor = Style.Current.LightBackground;
|
||||||
Offsets = new Margin(0, 0, y, height * Editor.Instance.Options.Options.Interface.IconsScale);
|
Offsets = new Margin(0, 0, y, height * Editor.Instance.Options.Options.Interface.IconsScale);
|
||||||
|
_itemsMargin = new Margin(2, 2, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -161,7 +170,7 @@ namespace FlaxEditor.GUI
|
|||||||
protected override void PerformLayoutBeforeChildren()
|
protected override void PerformLayoutBeforeChildren()
|
||||||
{
|
{
|
||||||
// Arrange controls
|
// Arrange controls
|
||||||
float x = DefaultMarginH;
|
float x = _itemsMargin.Left;
|
||||||
float h = ItemsHeight;
|
float h = ItemsHeight;
|
||||||
for (int i = 0; i < _children.Count; i++)
|
for (int i = 0; i < _children.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -169,8 +178,8 @@ namespace FlaxEditor.GUI
|
|||||||
if (c.Visible)
|
if (c.Visible)
|
||||||
{
|
{
|
||||||
var w = c.Width;
|
var w = c.Width;
|
||||||
c.Bounds = new Rectangle(x, DefaultMarginV, w, h);
|
c.Bounds = new Rectangle(x, _itemsMargin.Top, w, h);
|
||||||
x += w + DefaultMarginH;
|
x += w + _itemsMargin.Width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
private Margin _margin;
|
private Margin _margin;
|
||||||
private bool _autoSize = true;
|
private bool _autoSize = true;
|
||||||
private bool _deferLayoutUpdate = false;
|
private bool _deferLayoutUpdate = false;
|
||||||
|
private TreeNode _lastSelectedNode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The TreeNode that is being dragged over. This could have a value when not dragging.
|
/// The TreeNode that is being dragged over. This could have a value when not dragging.
|
||||||
@@ -67,7 +68,7 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
/// Gets the first selected node or null.
|
/// Gets the first selected node or null.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TreeNode SelectedNode => Selection.Count > 0 ? Selection[0] : null;
|
public TreeNode SelectedNode => Selection.Count > 0 ? Selection[0] : null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allow nodes to Draw the root tree line.
|
/// Allow nodes to Draw the root tree line.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -364,6 +365,19 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
BulkSelectUpdateExpanded(false);
|
BulkSelectUpdateExpanded(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flushes any pending layout perming action that has been delayed until next update to optimize performance of the complex tree hierarchy.
|
||||||
|
/// </summary>
|
||||||
|
public void FlushPendingPerformLayout()
|
||||||
|
{
|
||||||
|
if (_deferLayoutUpdate)
|
||||||
|
{
|
||||||
|
base.PerformLayout();
|
||||||
|
AfterDeferredLayout?.Invoke();
|
||||||
|
_deferLayoutUpdate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void PerformLayout(bool force = false)
|
public override void PerformLayout(bool force = false)
|
||||||
{
|
{
|
||||||
@@ -378,25 +392,31 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
public override void Update(float deltaTime)
|
public override void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
if (_deferLayoutUpdate)
|
if (_deferLayoutUpdate)
|
||||||
{
|
FlushPendingPerformLayout();
|
||||||
base.PerformLayout();
|
var window = Root;
|
||||||
AfterDeferredLayout?.Invoke();
|
bool shiftDown = window.GetKey(KeyboardKeys.Shift);
|
||||||
_deferLayoutUpdate = false;
|
bool keyUpArrow = window.GetKey(KeyboardKeys.ArrowUp);
|
||||||
}
|
bool keyDownArrow = window.GetKey(KeyboardKeys.ArrowDown);
|
||||||
|
|
||||||
var node = SelectedNode;
|
// Use last selection for last selected node if sift is down
|
||||||
|
if (Selection.Count < 2)
|
||||||
|
_lastSelectedNode = null;
|
||||||
|
else if (shiftDown)
|
||||||
|
_lastSelectedNode ??= Selection[^1];
|
||||||
|
|
||||||
|
// Skip root to prevent blocking input
|
||||||
|
if (_lastSelectedNode != null && _lastSelectedNode.IsRoot)
|
||||||
|
_lastSelectedNode = null;
|
||||||
|
|
||||||
|
var node = _lastSelectedNode ?? SelectedNode;
|
||||||
|
|
||||||
// Check if has focus and if any node is focused and it isn't a root
|
// Check if has focus and if any node is focused and it isn't a root
|
||||||
if (ContainsFocus && node != null && node.AutoFocus)
|
if (ContainsFocus && node != null && node.AutoFocus)
|
||||||
{
|
{
|
||||||
var window = Root;
|
|
||||||
if (window.GetKeyDown(KeyboardKeys.ArrowUp) || window.GetKeyDown(KeyboardKeys.ArrowDown))
|
if (window.GetKeyDown(KeyboardKeys.ArrowUp) || window.GetKeyDown(KeyboardKeys.ArrowDown))
|
||||||
_keyUpdateTime = KeyUpdateTimeout;
|
_keyUpdateTime = KeyUpdateTimeout;
|
||||||
if (_keyUpdateTime >= KeyUpdateTimeout && window is WindowRootControl windowRoot && windowRoot.Window.IsFocused)
|
if (_keyUpdateTime >= KeyUpdateTimeout && window is WindowRootControl windowRoot && windowRoot.Window.IsFocused)
|
||||||
{
|
{
|
||||||
bool keyUpArrow = window.GetKey(KeyboardKeys.ArrowUp);
|
|
||||||
bool keyDownArrow = window.GetKey(KeyboardKeys.ArrowDown);
|
|
||||||
|
|
||||||
// Check if arrow flags are different
|
// Check if arrow flags are different
|
||||||
if (keyDownArrow != keyUpArrow)
|
if (keyDownArrow != keyUpArrow)
|
||||||
{
|
{
|
||||||
@@ -406,24 +426,38 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
Assert.AreNotEqual(-1, myIndex);
|
Assert.AreNotEqual(-1, myIndex);
|
||||||
|
|
||||||
// Up
|
// Up
|
||||||
TreeNode toSelect = null;
|
List<TreeNode> toSelect = new List<TreeNode>();
|
||||||
|
if (shiftDown && _supportMultiSelect)
|
||||||
|
{
|
||||||
|
toSelect.AddRange(Selection);
|
||||||
|
}
|
||||||
if (keyUpArrow)
|
if (keyUpArrow)
|
||||||
{
|
{
|
||||||
if (myIndex == 0)
|
if (myIndex == 0)
|
||||||
{
|
{
|
||||||
// Select parent
|
// Select parent
|
||||||
toSelect = parentNode;
|
if (toSelect.Contains(parentNode))
|
||||||
|
toSelect.Remove(node);
|
||||||
|
else if (parentNode != null)
|
||||||
|
toSelect.Add(parentNode);
|
||||||
|
_lastSelectedNode = parentNode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Select previous parent child
|
// Select previous parent child
|
||||||
toSelect = nodeParent.GetChild(myIndex - 1) as TreeNode;
|
var select = nodeParent.GetChild(myIndex - 1) as TreeNode;
|
||||||
|
|
||||||
// Select last child if is valid and expanded and has any children
|
// Select last child if is valid and expanded and has any children
|
||||||
if (toSelect != null && toSelect.IsExpanded && toSelect.HasAnyVisibleChild)
|
if (select != null && select.IsExpanded && select.HasAnyVisibleChild)
|
||||||
{
|
{
|
||||||
toSelect = toSelect.GetChild(toSelect.ChildrenCount - 1) as TreeNode;
|
select = select.GetChild(select.ChildrenCount - 1) as TreeNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (select == null || toSelect.Contains(select))
|
||||||
|
toSelect.Remove(node);
|
||||||
|
else
|
||||||
|
toSelect.Add(select);
|
||||||
|
_lastSelectedNode = select;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Down
|
// Down
|
||||||
@@ -432,32 +466,48 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
if (node.IsExpanded && node.HasAnyVisibleChild)
|
if (node.IsExpanded && node.HasAnyVisibleChild)
|
||||||
{
|
{
|
||||||
// Select the first child
|
// Select the first child
|
||||||
toSelect = node.GetChild(0) as TreeNode;
|
var select = node.GetChild(0) as TreeNode;
|
||||||
|
if (select == null || toSelect.Contains(select))
|
||||||
|
toSelect.Remove(node);
|
||||||
|
else
|
||||||
|
toSelect.Add(select);
|
||||||
|
_lastSelectedNode = select;
|
||||||
}
|
}
|
||||||
else if (myIndex == nodeParent.ChildrenCount - 1)
|
else if (myIndex == nodeParent.ChildrenCount - 1)
|
||||||
{
|
{
|
||||||
// Select next node after parent
|
// Select next node after parent
|
||||||
while (parentNode != null && toSelect == null)
|
TreeNode select = null;
|
||||||
|
while (parentNode != null && select == null)
|
||||||
{
|
{
|
||||||
int parentIndex = parentNode.IndexInParent;
|
int parentIndex = parentNode.IndexInParent;
|
||||||
if (parentIndex != -1 && parentIndex < parentNode.Parent.ChildrenCount - 1)
|
if (parentIndex != -1 && parentIndex < parentNode.Parent.ChildrenCount - 1)
|
||||||
{
|
{
|
||||||
toSelect = parentNode.Parent.GetChild(parentIndex + 1) as TreeNode;
|
select = parentNode.Parent.GetChild(parentIndex + 1) as TreeNode;
|
||||||
}
|
}
|
||||||
parentNode = parentNode.Parent as TreeNode;
|
parentNode = parentNode.Parent as TreeNode;
|
||||||
}
|
}
|
||||||
|
if (select == null || toSelect.Contains(select))
|
||||||
|
toSelect.Remove(node);
|
||||||
|
else
|
||||||
|
toSelect.Add(select);
|
||||||
|
_lastSelectedNode = select;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Select next parent child
|
// Select next parent child
|
||||||
toSelect = nodeParent.GetChild(myIndex + 1) as TreeNode;
|
var select = nodeParent.GetChild(myIndex + 1) as TreeNode;
|
||||||
|
if (select == null || toSelect.Contains(select))
|
||||||
|
toSelect.Remove(node);
|
||||||
|
else
|
||||||
|
toSelect.Add(select);
|
||||||
|
_lastSelectedNode = select;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (toSelect != null && toSelect.AutoFocus)
|
if (toSelect.Count > 0)
|
||||||
{
|
{
|
||||||
// Select
|
// Select
|
||||||
Select(toSelect);
|
Select(toSelect);
|
||||||
toSelect.Focus();
|
_lastSelectedNode?.Focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset time
|
// Reset time
|
||||||
|
|||||||
@@ -319,6 +319,8 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
public TreeNode(bool canChangeOrder, SpriteHandle iconCollapsed, SpriteHandle iconOpened)
|
public TreeNode(bool canChangeOrder, SpriteHandle iconCollapsed, SpriteHandle iconOpened)
|
||||||
: base(0, 0, 64, 16)
|
: base(0, 0, 64, 16)
|
||||||
{
|
{
|
||||||
|
AutoFocus = true;
|
||||||
|
|
||||||
_canChangeOrder = canChangeOrder;
|
_canChangeOrder = canChangeOrder;
|
||||||
_animationProgress = 1.0f;
|
_animationProgress = 1.0f;
|
||||||
_cachedHeight = _headerHeight;
|
_cachedHeight = _headerHeight;
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ namespace FlaxEditor.Gizmo
|
|||||||
// Ensure player is not moving objects
|
// Ensure player is not moving objects
|
||||||
if (ActiveAxis != Axis.None)
|
if (ActiveAxis != Axis.None)
|
||||||
return;
|
return;
|
||||||
|
Profiler.BeginEvent("Pick");
|
||||||
|
|
||||||
// Get mouse ray and try to hit any object
|
// Get mouse ray and try to hit any object
|
||||||
var ray = Owner.MouseRay;
|
var ray = Owner.MouseRay;
|
||||||
@@ -243,6 +244,8 @@ namespace FlaxEditor.Gizmo
|
|||||||
{
|
{
|
||||||
sceneEditing.Deselect();
|
sceneEditing.Deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Profiler.EndEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using FlaxEditor.Options;
|
using FlaxEditor.Options;
|
||||||
using FlaxEditor.SceneGraph;
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace FlaxEditor.Gizmo
|
namespace FlaxEditor.Gizmo
|
||||||
{
|
{
|
||||||
@@ -21,12 +19,16 @@ namespace FlaxEditor.Gizmo
|
|||||||
private MaterialInstance _materialAxisY;
|
private MaterialInstance _materialAxisY;
|
||||||
private MaterialInstance _materialAxisZ;
|
private MaterialInstance _materialAxisZ;
|
||||||
private MaterialInstance _materialAxisFocus;
|
private MaterialInstance _materialAxisFocus;
|
||||||
private MaterialInstance _materialAxisLocked;
|
|
||||||
private MaterialBase _materialSphere;
|
private MaterialBase _materialSphere;
|
||||||
|
|
||||||
// Material Parameter Names
|
// Material Parameter Names
|
||||||
const String _brightnessParamName = "Brightness";
|
private const string _brightnessParamName = "Brightness";
|
||||||
const String _opacityParamName = "Opacity";
|
private const string _opacityParamName = "Opacity";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used for example when the selection can't be moved because one actor is static.
|
||||||
|
/// </summary>
|
||||||
|
private bool _isDisabled;
|
||||||
|
|
||||||
private void InitDrawing()
|
private void InitDrawing()
|
||||||
{
|
{
|
||||||
@@ -42,7 +44,6 @@ namespace FlaxEditor.Gizmo
|
|||||||
_materialAxisY = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisY");
|
_materialAxisY = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisY");
|
||||||
_materialAxisZ = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisZ");
|
_materialAxisZ = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisZ");
|
||||||
_materialAxisFocus = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisFocus");
|
_materialAxisFocus = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisFocus");
|
||||||
_materialAxisLocked = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisLocked");
|
|
||||||
_materialSphere = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialSphere");
|
_materialSphere = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialSphere");
|
||||||
|
|
||||||
// Ensure that every asset was loaded
|
// Ensure that every asset was loaded
|
||||||
@@ -67,17 +68,42 @@ namespace FlaxEditor.Gizmo
|
|||||||
|
|
||||||
private void OnEditorOptionsChanged(EditorOptions options)
|
private void OnEditorOptionsChanged(EditorOptions options)
|
||||||
{
|
{
|
||||||
float brightness = options.Visual.TransformGizmoBrightness;
|
UpdateGizmoBrightness(options);
|
||||||
_materialAxisX.SetParameterValue(_brightnessParamName, brightness);
|
|
||||||
_materialAxisY.SetParameterValue(_brightnessParamName, brightness);
|
|
||||||
_materialAxisZ.SetParameterValue(_brightnessParamName, brightness);
|
|
||||||
_materialAxisLocked.SetParameterValue(_brightnessParamName, brightness);
|
|
||||||
|
|
||||||
float opacity = options.Visual.TransformGizmoOpacity;
|
float opacity = options.Visual.TransformGizmoOpacity;
|
||||||
_materialAxisX.SetParameterValue(_opacityParamName, opacity);
|
_materialAxisX.SetParameterValue(_opacityParamName, opacity);
|
||||||
_materialAxisY.SetParameterValue(_opacityParamName, opacity);
|
_materialAxisY.SetParameterValue(_opacityParamName, opacity);
|
||||||
_materialAxisZ.SetParameterValue(_opacityParamName, opacity);
|
_materialAxisZ.SetParameterValue(_opacityParamName, opacity);
|
||||||
_materialAxisLocked.SetParameterValue(_opacityParamName, opacity);
|
}
|
||||||
|
|
||||||
|
private void UpdateGizmoBrightness(EditorOptions options)
|
||||||
|
{
|
||||||
|
_isDisabled = ShouldGizmoBeLocked();
|
||||||
|
|
||||||
|
float brightness = _isDisabled ? options.Visual.TransformGizmoBrightnessDisabled : options.Visual.TransformGizmoBrightness;
|
||||||
|
if (Mathf.NearEqual(brightness, (float)_materialAxisX.GetParameterValue(_brightnessParamName)))
|
||||||
|
return;
|
||||||
|
_materialAxisX.SetParameterValue(_brightnessParamName, brightness);
|
||||||
|
_materialAxisY.SetParameterValue(_brightnessParamName, brightness);
|
||||||
|
_materialAxisZ.SetParameterValue(_brightnessParamName, brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldGizmoBeLocked()
|
||||||
|
{
|
||||||
|
bool gizmoLocked = false;
|
||||||
|
if (Editor.Instance.StateMachine.IsPlayMode && Owner is Viewport.EditorGizmoViewport)
|
||||||
|
{
|
||||||
|
// Block editing static scene objects in main view during play mode
|
||||||
|
foreach (var obj in Editor.Instance.SceneEditing.Selection)
|
||||||
|
{
|
||||||
|
if (obj.CanTransform == false)
|
||||||
|
{
|
||||||
|
gizmoLocked = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gizmoLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -88,20 +114,8 @@ namespace FlaxEditor.Gizmo
|
|||||||
if (!_modelCube || !_modelCube.IsLoaded)
|
if (!_modelCube || !_modelCube.IsLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Find out if any of the selected objects can not be moved
|
// Update the gizmo brightness every frame to ensure it updates correctly
|
||||||
bool gizmoLocked = false;
|
UpdateGizmoBrightness(Editor.Instance.Options.Options);
|
||||||
if (Editor.Instance.StateMachine.IsPlayMode)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < SelectionCount; i++)
|
|
||||||
{
|
|
||||||
var obj = GetSelectedObject(i);
|
|
||||||
if (obj.CanTransform == false)
|
|
||||||
{
|
|
||||||
gizmoLocked = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// As all axisMesh have the same pivot, add a little offset to the x axisMesh, this way SortDrawCalls is able to sort the draw order
|
// As all axisMesh have the same pivot, add a little offset to the x axisMesh, this way SortDrawCalls is able to sort the draw order
|
||||||
// https://github.com/FlaxEngine/FlaxEngine/issues/680
|
// https://github.com/FlaxEngine/FlaxEngine/issues/680
|
||||||
@@ -136,37 +150,37 @@ namespace FlaxEditor.Gizmo
|
|||||||
// X axis
|
// X axis
|
||||||
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance xAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xAxisMaterialTransform = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance yAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance yAxisMaterialTransform = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(Mathf.Pi, out m2);
|
Matrix.RotationX(Mathf.Pi, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance zAxisMaterialTransform = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// XY plane
|
// XY plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance xyPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xyPlaneMaterialTransform = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// ZX plane
|
// ZX plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zxPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance zxPlaneMaterialTransform = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// YZ plane
|
// YZ plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance yzPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance yzPlaneMaterialTransform = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center sphere
|
// Center sphere
|
||||||
@@ -186,17 +200,17 @@ namespace FlaxEditor.Gizmo
|
|||||||
// X axis
|
// X axis
|
||||||
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
|
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance yAxisMaterialRotate = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
rotationAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m1, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
rotationAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m1, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(-Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(-Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center box
|
// Center box
|
||||||
@@ -216,37 +230,37 @@ namespace FlaxEditor.Gizmo
|
|||||||
// X axis
|
// X axis
|
||||||
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref mx1, out m3);
|
Matrix.Multiply(ref m2, ref mx1, out m3);
|
||||||
MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance yAxisMaterialRotate = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(Mathf.Pi, out m2);
|
Matrix.RotationX(Mathf.Pi, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// XY plane
|
// XY plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance xyPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xyPlaneMaterialScale = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// ZX plane
|
// ZX plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zxPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance zxPlaneMaterialScale = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// YZ plane
|
// YZ plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance yzPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance yzPlaneMaterialScale = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center box
|
// Center box
|
||||||
|
|||||||
@@ -155,6 +155,16 @@ namespace FlaxEditor
|
|||||||
private List<Widget> _widgets;
|
private List<Widget> _widgets;
|
||||||
private Widget _activeWidget;
|
private Widget _activeWidget;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the view size.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="size">The new size.</param>
|
||||||
|
public void SetViewSize(Float2 size)
|
||||||
|
{
|
||||||
|
_view.Size = size;
|
||||||
|
_view.PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// True if enable displaying UI editing background and grid elements.
|
/// True if enable displaying UI editing background and grid elements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MException.h"
|
#include "Engine/Scripting/ManagedCLR/MException.h"
|
||||||
#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h"
|
#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h"
|
||||||
|
#include "Engine/Platform/WindowsManager.h"
|
||||||
#include "Engine/Content/Assets/VisualScript.h"
|
#include "Engine/Content/Assets/VisualScript.h"
|
||||||
#include "Engine/Content/Content.h"
|
#include "Engine/Content/Content.h"
|
||||||
#include "Engine/Level/Actor.h"
|
#include "Engine/Level/Actor.h"
|
||||||
@@ -627,6 +628,14 @@ void ManagedEditor::WipeOutLeftoverSceneObjects()
|
|||||||
ObjectsRemovalService::Flush();
|
ObjectsRemovalService::Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array<Window*> ManagedEditor::GetWindows()
|
||||||
|
{
|
||||||
|
WindowsManager::WindowsLocker.Lock();
|
||||||
|
auto result = WindowsManager::Windows;
|
||||||
|
WindowsManager::WindowsLocker.Unlock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void ManagedEditor::OnEditorAssemblyLoaded(MAssembly* assembly)
|
void ManagedEditor::OnEditorAssemblyLoaded(MAssembly* assembly)
|
||||||
{
|
{
|
||||||
ASSERT(!HasManagedInstance());
|
ASSERT(!HasManagedInstance());
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ public:
|
|||||||
API_FUNCTION(Internal) static Array<VisualScriptLocal> GetVisualScriptLocals();
|
API_FUNCTION(Internal) static Array<VisualScriptLocal> GetVisualScriptLocals();
|
||||||
API_FUNCTION(Internal) static bool EvaluateVisualScriptLocal(VisualScript* script, API_PARAM(Ref) VisualScriptLocal& local);
|
API_FUNCTION(Internal) static bool EvaluateVisualScriptLocal(VisualScript* script, API_PARAM(Ref) VisualScriptLocal& local);
|
||||||
API_FUNCTION(Internal) static void WipeOutLeftoverSceneObjects();
|
API_FUNCTION(Internal) static void WipeOutLeftoverSceneObjects();
|
||||||
|
API_FUNCTION(Internal) static Array<Window*> GetWindows();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnEditorAssemblyLoaded(MAssembly* assembly);
|
void OnEditorAssemblyLoaded(MAssembly* assembly);
|
||||||
|
|||||||
@@ -254,18 +254,29 @@ namespace FlaxEditor.Modules
|
|||||||
PrefabApplying?.Invoke(prefab, instance);
|
PrefabApplying?.Invoke(prefab, instance);
|
||||||
|
|
||||||
// When applying changes to prefab from actor in level ignore it's root transformation (see ActorEditor.ProcessDiff)
|
// When applying changes to prefab from actor in level ignore it's root transformation (see ActorEditor.ProcessDiff)
|
||||||
|
Actor prefabRoot = null;
|
||||||
var originalTransform = instance.LocalTransform;
|
var originalTransform = instance.LocalTransform;
|
||||||
var originalName = instance.Name;
|
var originalName = instance.Name;
|
||||||
if (instance.IsPrefabRoot && instance.HasScene)
|
if (instance.HasScene)
|
||||||
{
|
{
|
||||||
instance.LocalTransform = prefab.GetDefaultInstance().Transform;
|
prefabRoot = instance.GetPrefabRoot();
|
||||||
instance.Name = prefab.GetDefaultInstance().Name;
|
if (prefabRoot != null && prefabRoot.IsPrefabRoot && instance.HasScene)
|
||||||
|
{
|
||||||
|
var defaultInstance = prefab.GetDefaultInstance();
|
||||||
|
originalTransform = prefabRoot.LocalTransform;
|
||||||
|
originalName = prefabRoot.Name;
|
||||||
|
prefabRoot.LocalTransform = defaultInstance.Transform;
|
||||||
|
prefabRoot.Name = defaultInstance.Name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call backend
|
// Call backend
|
||||||
var failed = PrefabManager.Internal_ApplyAll(FlaxEngine.Object.GetUnmanagedPtr(instance));
|
var failed = PrefabManager.Internal_ApplyAll(FlaxEngine.Object.GetUnmanagedPtr(instance));
|
||||||
instance.LocalTransform = originalTransform;
|
if (prefabRoot != null)
|
||||||
instance.Name = originalName;
|
{
|
||||||
|
prefabRoot.LocalTransform = originalTransform;
|
||||||
|
prefabRoot.Name = originalName;
|
||||||
|
}
|
||||||
if (failed)
|
if (failed)
|
||||||
throw new Exception("Failed to apply the prefab. See log to learn more.");
|
throw new Exception("Failed to apply the prefab. See log to learn more.");
|
||||||
|
|
||||||
|
|||||||
@@ -673,6 +673,7 @@ namespace FlaxEditor.Modules
|
|||||||
pasteAction.Do(out _, out var nodeParents);
|
pasteAction.Do(out _, out var nodeParents);
|
||||||
|
|
||||||
// Select spawned objects (parents only)
|
// Select spawned objects (parents only)
|
||||||
|
newSelection.Clear();
|
||||||
newSelection.AddRange(nodeParents);
|
newSelection.AddRange(nodeParents);
|
||||||
var selectAction = new SelectionChangeAction(Selection.ToArray(), newSelection.ToArray(), OnSelectionUndo);
|
var selectAction = new SelectionChangeAction(Selection.ToArray(), newSelection.ToArray(), OnSelectionUndo);
|
||||||
selectAction.Do();
|
selectAction.Do();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user