Compare commits
462 Commits
signalgame
...
sdl3
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ba7351206 | |||
| 7c901a56e5 | |||
| 8ba44e75a4 | |||
| 7cadc8d331 | |||
| 7debd885b9 | |||
| 44a9c52c44 | |||
| dcc444173d | |||
| d3c4b5b8c1 | |||
| 56236b0579 | |||
| c2a588f738 | |||
| 09331b601b | |||
| 17d7716e41 | |||
| 0344cde98f | |||
| 9f35f175ab | |||
| cabf8736c7 | |||
| 93344a33d3 | |||
| 3898df1b68 | |||
| 33909cf931 | |||
| 3bc70c147b | |||
| 70dea56d44 | |||
| 348e15475f | |||
| fe568cf16a | |||
| 1066a38130 | |||
| 2494c3cb23 | |||
| ecc34320d1 | |||
|
|
9f078a6e3c | ||
|
|
b4d1e6197c | ||
|
|
d14a4f1f66 | ||
|
|
1e43b031ba | ||
|
|
41fd7b724e | ||
|
|
2a1706decb | ||
|
|
ab7de52531 | ||
|
|
1891b9e367 | ||
|
|
3ac7dfbd3a | ||
|
|
2853273205 | ||
|
|
2201dd681e | ||
|
|
013dab4ba7 | ||
|
|
cf501945a3 | ||
|
|
ab4703c3dd | ||
|
|
4ce853d892 | ||
|
|
6cdd56ad11 | ||
|
|
66122e6e3b | ||
|
|
c444661884 | ||
|
|
91a8a670d5 | ||
|
|
dbd5566ee0 | ||
|
|
ad2d4a2626 | ||
|
|
148f03205f | ||
|
|
2c1f835528 | ||
|
|
8038e045b0 | ||
|
|
7a635e2896 | ||
|
|
a40a5721f3 | ||
|
|
e4cf4c9f17 | ||
|
|
5299afa276 | ||
|
|
8e8e41d5e1 | ||
|
|
153e45c345 | ||
|
|
7bb365c57b | ||
|
|
8397a81428 | ||
|
|
17c484b97b | ||
|
|
3b740659f5 | ||
|
|
2913bb39e8 | ||
|
|
8209639261 | ||
|
|
a580d6785f | ||
| 8b22ffe007 | |||
| 24f7ec4a54 | |||
| 55d55212c3 | |||
|
|
1142fa68ea | ||
|
|
305f725394 | ||
|
|
8a297a6fd4 | ||
|
|
d717430256 | ||
|
|
8804738193 | ||
|
|
9b11461eaf | ||
|
|
d879b8e064 | ||
|
|
f132198ead | ||
|
|
5e0d90af2e | ||
|
|
736119fdc6 | ||
|
|
5259c41b40 | ||
|
|
4a6f2f8821 | ||
|
|
529de24da4 | ||
|
|
fc3d15c544 | ||
|
|
261c4a7e88 | ||
|
|
ccd619f659 | ||
|
|
35bbd52f89 | ||
|
|
ea45aa9b19 | ||
|
|
655c377da8 | ||
|
|
5498cbf3bf | ||
|
|
10a343a490 | ||
|
|
b2faad9634 | ||
|
|
786ab54f84 | ||
|
|
d41d153cff | ||
|
|
89bd733142 | ||
|
|
5d2a1e0507 | ||
|
|
22ff68b89f | ||
|
|
fe41ef619b | ||
|
|
3870a013fa | ||
|
|
ebd890a0da | ||
|
|
964a1940c4 | ||
|
|
b11af95ec7 | ||
|
|
e8de6c37fc | ||
|
|
af41cefaac | ||
|
|
900a96938b | ||
|
|
c58d43ac1e | ||
|
|
0122ee94a5 | ||
|
|
dfb541011d | ||
|
|
85a04f8e81 | ||
|
|
531c75bff9 | ||
|
|
12f70572b0 | ||
|
|
7090e85224 | ||
|
|
e5e1f945ea | ||
|
|
e1cf41b94b | ||
|
|
d4bf8368b1 | ||
|
|
6588a71879 | ||
|
|
d700df6afb | ||
| 35d46e23a8 | |||
| f1fc086612 | |||
|
|
7b4e509140 | ||
|
|
c168ce3a7e | ||
|
|
e1dcd290b1 | ||
|
|
009e1aaebb | ||
|
|
fe9996dd4f | ||
|
|
d1e54b821b | ||
|
|
8877aac8cb | ||
|
|
a61096ffa5 | ||
|
|
751c1f20dc | ||
|
|
f40cf6539a | ||
|
|
8e4f7babf3 | ||
|
|
e18b059234 | ||
|
|
e3114c29af | ||
|
|
3539f84c9a | ||
|
|
5b0c6d1aff | ||
|
|
1b72b14376 | ||
|
|
32af6ede73 | ||
|
|
a79fb237e5 | ||
|
|
ec510425a1 | ||
|
|
bf772a5eb9 | ||
|
|
fe3a9fbd67 | ||
|
|
090b9ea0c1 | ||
|
|
ddfaeddb5f | ||
|
|
abe938c30a | ||
|
|
cf02fecadc | ||
|
|
54c24f8434 | ||
|
|
35ab0f4261 | ||
|
|
73342615d1 | ||
|
|
d64108a5c1 | ||
|
|
1dfa92b0c3 | ||
| d56493da54 | |||
| 16b0228394 | |||
|
|
cb3e8e4112 | ||
|
|
5f4aee71b8 | ||
|
|
02403377cd | ||
| 6436fb3bde | |||
|
|
a1adab1156 | ||
|
|
919e118a2f | ||
|
|
f38df259a7 | ||
|
|
ec10e3bb30 | ||
|
|
224c2c049e | ||
|
|
8509761d67 | ||
|
|
0d8691045b | ||
|
|
bd727ae189 | ||
|
|
4bfda76666 | ||
|
|
a030978558 | ||
|
|
2aff3d76ca | ||
|
|
8312659275 | ||
|
|
55ce33bc1c | ||
|
|
1613bdcd06 | ||
|
|
a67dc00fa3 | ||
| 1c82c73bc0 | |||
|
|
a05fe5ce9b | ||
|
|
8899e3ebb7 | ||
|
|
727ff8be95 | ||
|
|
a8d97f1daa | ||
|
|
488485e23e | ||
|
|
79138dfaf0 | ||
|
|
f52059522b | ||
| 691ac6d439 | |||
|
|
6fc056cba2 | ||
|
|
54cb82cbda | ||
|
|
b8c9130ae4 | ||
|
|
c2e1b92cce | ||
|
|
6113325e07 | ||
|
|
bea7e1526d | ||
|
|
abc75e6c3d | ||
|
|
dfc1db672d | ||
|
|
5b71591998 | ||
|
|
4dabf4bf01 | ||
|
|
210c443b30 | ||
|
|
f95e7e96bf | ||
|
|
735aa70b53 | ||
|
|
b1fd178341 | ||
|
|
0bb21ef4a0 | ||
|
|
2a4a5d2519 | ||
|
|
892ab47b7a | ||
|
|
7f6805aac6 | ||
|
|
d56d624f0f | ||
|
|
fd91e912fe | ||
|
|
7106791186 | ||
|
|
a0f379f613 | ||
|
|
c0847f6789 | ||
|
|
831289afc3 | ||
| 7ba97f3c32 | |||
| 992436b47c | |||
| 7614481d78 | |||
| 07371ddfdf | |||
|
|
50c29f6a9b | ||
|
|
a4877c6294 | ||
|
|
c9bebc0700 | ||
|
|
26867bfd8f | ||
|
|
dfd6df7f42 | ||
|
|
092681aea7 | ||
|
|
3a2f4843ba | ||
|
|
db6cdc3ce0 | ||
|
|
b23aa6cebd | ||
|
|
2676daabf1 | ||
|
|
c82e67083f | ||
|
|
175fd31431 | ||
|
|
3b1a96582a | ||
|
|
2b46f04baf | ||
|
|
106b48f4d5 | ||
|
|
732b34d28b | ||
|
|
116539ce34 | ||
|
|
e8421d4274 | ||
|
|
0b9ee23a5c | ||
|
|
2d2841d59e | ||
|
|
a0c2f6a51e | ||
|
|
1d946afe82 | ||
|
|
6ea519b55a | ||
|
|
2d6c49ee20 | ||
|
|
59b250f091 | ||
|
|
6c347f08b6 | ||
|
|
304f24764b | ||
|
|
3dac26ffda | ||
|
|
f51a442357 | ||
|
|
d4145179a9 | ||
| bf5e5d1254 | |||
| adbe43c2c2 | |||
| 974e3e192b | |||
| 2283a15172 | |||
| c4d5e50f22 | |||
| 86d90605fc | |||
| db71bf2868 | |||
| fef124a01d | |||
| 272977a521 | |||
| dedb3d57fd | |||
|
|
0fc507e238 | ||
|
|
9e9013ec43 | ||
|
|
0c50fa9816 | ||
|
|
83ccb79fa3 | ||
|
|
8b72c063a8 | ||
|
|
e0791eacad | ||
|
|
11ec018933 | ||
|
|
8ef1cad6fb | ||
|
|
6885e561db | ||
|
|
806bff19f4 | ||
|
|
949057b1c3 | ||
|
|
5c23f4ac09 | ||
|
|
cdd53f09b9 | ||
|
|
f3210608ae | ||
|
|
f01784108d | ||
|
|
30c1068a13 | ||
|
|
3f3df090f4 | ||
|
|
390f574662 | ||
|
|
48a09c9783 | ||
|
|
981109a6f1 | ||
|
|
2f8428db1a | ||
|
|
d0ec3fa2e2 | ||
|
|
9533289e57 | ||
|
|
0f485cf77c | ||
|
|
8c8b4613d2 | ||
|
|
3b872f08a8 | ||
|
|
e89e0159bf | ||
|
|
857d2c26f4 | ||
|
|
49e70637db | ||
|
|
72a151816a | ||
|
|
528b20dc00 | ||
|
|
ce2d2b78c4 | ||
|
|
b22c42b9e3 | ||
|
|
377d25a1fd | ||
|
|
32a60c3b5c | ||
|
|
3f40aff01f | ||
|
|
09563caf37 | ||
|
|
130fc5b54d | ||
|
|
e15a848ac6 | ||
|
|
1729fe6993 | ||
|
|
cc01e88ce8 | ||
|
|
f18715a497 | ||
|
|
d47a191d5c | ||
|
|
afdae7f670 | ||
|
|
7c4b8758ea | ||
|
|
f22e559e83 | ||
|
|
9731437717 | ||
|
|
6f7bb8dbf2 | ||
|
|
3dd83c52bf | ||
|
|
949ac08643 | ||
|
|
4948b1b86a | ||
|
|
e5bf0e1b9f | ||
|
|
b776465919 | ||
|
|
82181b28b0 | ||
|
|
eb07fd7b9a | ||
|
|
79dbad6547 | ||
|
|
94884fc39a | ||
|
|
aec5ef8332 | ||
|
|
8e4783a0c6 | ||
|
|
c23f2b61cc | ||
|
|
6481897ffa | ||
|
|
499a7c6129 | ||
|
|
84fdf9cc80 | ||
|
|
f8d023ed5c | ||
|
|
5ca61d8568 | ||
|
|
58998f4576 | ||
|
|
c486577b07 | ||
|
|
a69c8ce6a2 | ||
|
|
e527783e55 | ||
|
|
4d9c92dd49 | ||
|
|
9b01229e58 | ||
|
|
e3a030fad8 | ||
|
|
cb878294ea | ||
|
|
b2fc5e8fd3 | ||
|
|
4fb42319ef | ||
|
|
1bd1aca0f0 | ||
|
|
b433312042 | ||
|
|
1041b1b86d | ||
|
|
1ace5fd10d | ||
|
|
cfc9f73744 | ||
|
|
2418167182 | ||
|
|
52090d3a6b | ||
|
|
73f68c102d | ||
|
|
862dd1e5f1 | ||
| 58351d1989 | |||
|
|
6705205e2f | ||
|
|
2cdd0ff644 | ||
|
|
69ae841f64 | ||
|
|
7f8700288f | ||
|
|
f87dec6ca6 | ||
|
|
65a6c0aed5 | ||
|
|
f6dd0decfb | ||
|
|
816984542a | ||
|
|
3837e8b263 | ||
|
|
47b3141f18 | ||
|
|
e10ee3e55a | ||
|
|
0a4e89e29b | ||
|
|
0765fa92b5 | ||
|
|
2529312152 | ||
|
|
3404643636 | ||
|
|
6b9f6ac82e | ||
|
|
ab5bb79754 | ||
|
|
58f95d6ce3 | ||
|
|
1cd2f6a070 | ||
|
|
35ddfc2455 | ||
|
|
17d1d87268 | ||
|
|
fd871ce830 | ||
|
|
b4a4a8a591 | ||
|
|
24e4015425 | ||
|
|
c670887b1a | ||
|
|
d3cd6a461b | ||
|
|
2625a9d762 | ||
|
|
4fdd9a242b | ||
|
|
a6e8e6f749 | ||
|
|
03eabbcf63 | ||
|
|
13f94dcf11 | ||
|
|
3b44062eb0 | ||
|
|
1457637707 | ||
|
|
d28567111f | ||
|
|
1c7f06e570 | ||
|
|
63cc0fef2e | ||
|
|
57084b3d6c | ||
|
|
fa23619f08 | ||
|
|
1f2456fc67 | ||
|
|
0b71e906a6 | ||
|
|
2e59c35a44 | ||
|
|
6f2bd0e932 | ||
|
|
6a883bc7c6 | ||
|
|
17de6388ca | ||
|
|
e028d263f1 | ||
|
|
6962ed6730 | ||
|
|
b66d50ae1b | ||
|
|
675ce71935 | ||
|
|
833f844d59 | ||
|
|
af08dc1c69 | ||
|
|
07628d2ec7 | ||
|
|
aac3dbfe09 | ||
|
|
185f24ce49 | ||
| 77e29109ee | |||
| 8d89b9efb0 | |||
|
|
b2fee31a13 | ||
|
|
fc7628e2ee | ||
|
|
2e3e4959d6 | ||
|
|
f22105c2c3 | ||
|
|
533902d185 | ||
|
|
68653fa91f | ||
|
|
dc0aa61a14 | ||
|
|
ee790ff3a9 | ||
|
|
a2a3926aee | ||
|
|
9a70344c1f | ||
|
|
44006dd533 | ||
|
|
f6aabf2d14 | ||
|
|
dc1f15f18d | ||
|
|
7d7808af8f | ||
|
|
5029584a9f | ||
|
|
f353d3f114 | ||
|
|
667e8bc293 | ||
|
|
2edb9cc4d8 | ||
|
|
7018666a8c | ||
|
|
f04926ad94 | ||
| 50f5f0acd9 | |||
|
|
3745979b81 | ||
|
|
db15f6f08a | ||
|
|
e1a2f51d5a | ||
|
|
a8e1fd7a4a | ||
|
|
d46ef6ac92 | ||
|
|
36d21b27c7 | ||
|
|
b1636c27e7 | ||
|
|
5d32fc6c5e | ||
|
|
065dc474c0 | ||
|
|
1fb7b24aad | ||
|
|
f0b72aa025 | ||
|
|
058077736b | ||
|
|
b02f011627 | ||
| ea04c746fd | |||
| 97454fc82e | |||
|
|
4a6afdb108 | ||
|
|
65e852600a | ||
|
|
fedd990c13 | ||
|
|
c0329abe40 | ||
|
|
d8850a56a8 | ||
|
|
e171bb06ec | ||
|
|
3825e07adc | ||
|
|
db8adf7d96 | ||
| e77ae12b9b | |||
|
|
bf4e4aeaf6 | ||
|
|
2107b069db | ||
|
|
ea2005dacb | ||
|
|
d5cded8aaa | ||
|
|
430b22d5d7 | ||
|
|
9d830eb1e2 | ||
|
|
7e3f84f95e | ||
|
|
cddee38d71 | ||
|
|
e030d0461b | ||
|
|
4978c8e0d9 | ||
|
|
dc7b7e6e10 | ||
|
|
1e3eb11b94 | ||
|
|
b15b231b85 | ||
|
|
262992571a | ||
|
|
352bf3f9a7 | ||
|
|
9683868767 | ||
|
|
40284fbbf8 | ||
|
|
0c86a900da | ||
|
|
c1e3eaeab1 | ||
|
|
3c487dff47 | ||
|
|
2260d79e26 | ||
|
|
3209320547 | ||
|
|
d1db06a9bb | ||
|
|
1c1d2fd96f | ||
|
|
2e5ad8c48a | ||
|
|
9a6f866956 | ||
|
|
d8ca8f5985 | ||
|
|
ac36297e27 | ||
|
|
7fef21218e | ||
| 7aa4ae1782 | |||
| dd7739f95e | |||
|
|
203f5d06d1 | ||
|
|
c6515da8c9 | ||
|
|
5d61e45ecd | ||
|
|
2bec653b81 |
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/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/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
@@ -16,6 +16,7 @@
|
||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||
@2// Forward Shading: Constants
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
@@ -25,9 +26,9 @@ LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
@3// Forward Shading: Resources
|
||||
TextureCube EnvProbe : register(t__SRV__);
|
||||
TextureCube SkyLightTexture : register(t__SRV__);
|
||||
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
||||
Texture2D<float> ShadowMap : register(t__SRV__);
|
||||
Texture2DArray DirectionalLightShadowMap : register(t__SRV__);
|
||||
@4// Forward Shading: Utilities
|
||||
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
@5// Forward Shading: Shaders
|
||||
|
||||
// Pixel Shader function for Forward Pass
|
||||
@@ -79,8 +80,11 @@ void PS_Forward(
|
||||
|
||||
// Calculate lighting from a single directional light
|
||||
float4 shadowMask = 1.0f;
|
||||
ShadowSample shadow = SampleDirectionalLightShadow(DirectionalLight, ShadowsBuffer, ShadowMap, gBuffer);
|
||||
shadowMask = GetShadowMask(shadow);
|
||||
if (DirectionalLight.CastShadows > 0)
|
||||
{
|
||||
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||
}
|
||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||
|
||||
// Calculate lighting from sky light
|
||||
|
||||
@@ -26,7 +26,7 @@ struct RibbonInput
|
||||
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x3 WorldMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
uint SortedIndicesOffset;
|
||||
float PerInstanceRandom;
|
||||
int ParticleStride;
|
||||
@@ -45,7 +45,7 @@ int RibbonWidthOffset;
|
||||
int RibbonTwistOffset;
|
||||
int RibbonFacingVectorOffset;
|
||||
uint RibbonSegmentCount;
|
||||
float4x3 WorldMatrixInverseTransposed;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
@1META_CB_END
|
||||
|
||||
// Particles attributes buffer
|
||||
@@ -138,7 +138,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
||||
#if USE_INSTANCING
|
||||
#define GetInstanceTransform(input) float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f))
|
||||
#else
|
||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
||||
#define GetInstanceTransform(input) WorldMatrix;
|
||||
#endif
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
@@ -264,12 +264,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
|
||||
float3 TransformParticlePosition(float3 input)
|
||||
{
|
||||
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||
return mul(float4(input, 1.0f), WorldMatrix).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
}
|
||||
|
||||
@8
|
||||
@@ -333,7 +333,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
||||
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
|
||||
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
|
||||
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
float4x4 world = WorldMatrix;
|
||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||
float3x3 viewRot = transpose((float3x3)ViewMatrix);
|
||||
float3 position = mul(float4(particlePosition, 1), world).xyz;
|
||||
@@ -463,12 +463,11 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
}
|
||||
|
||||
// Read particle data
|
||||
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
||||
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
|
||||
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
|
||||
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
|
||||
int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1;
|
||||
float3 position = mul(float4(particlePosition, 1), worldMatrix).xyz;
|
||||
float3 position = mul(float4(particlePosition, 1), WorldMatrix).xyz;
|
||||
|
||||
// Compute final vertex position in the world
|
||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||
@@ -507,7 +506,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
world = mul(world, scaleMatrix);
|
||||
}
|
||||
world = transpose(world);
|
||||
world = mul(world, worldMatrix);
|
||||
world = mul(world, WorldMatrix);
|
||||
|
||||
// Calculate the vertex position in world space
|
||||
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
|
||||
@@ -521,12 +520,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = input.Color;
|
||||
#endif
|
||||
output.InstanceOrigin = worldMatrix[3].xyz;
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = CalcTangentToLocal(input);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
output.TBN = tangentToWorld;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
@@ -626,13 +625,12 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = 1;
|
||||
#endif
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
output.InstanceOrigin = world[3].xyz;
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
output.TBN = tangentToWorld;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x3 WorldMatrix;
|
||||
float4x3 PrevWorldMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 PrevWorldMatrix;
|
||||
float2 Dummy0;
|
||||
float LODDitherFactor;
|
||||
float PerInstanceRandom;
|
||||
@@ -171,7 +171,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
||||
#if USE_INSTANCING
|
||||
#define CalculateInstanceTransform(input) float4x4 world = GetInstanceTransform(input); output.Geometry.InstanceTransform1 = input.InstanceTransform1.xyz; output.Geometry.InstanceTransform2 = input.InstanceTransform2.xyz; output.Geometry.InstanceTransform3 = input.InstanceTransform3.xyz;
|
||||
#else
|
||||
#define CalculateInstanceTransform(input) float4x4 world = ToMatrix4x4(WorldMatrix); output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz;
|
||||
#define CalculateInstanceTransform(input) float4x4 world = WorldMatrix; output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz;
|
||||
#endif
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
@@ -328,7 +328,7 @@ VertexOutput VS(ModelInput input)
|
||||
// Compute world space vertex position
|
||||
CalculateInstanceTransform(input);
|
||||
output.Geometry.WorldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), PrevWorldMatrix).xyz;
|
||||
|
||||
// Compute clip space position
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -402,7 +402,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
|
||||
#if USE_INSTANCING
|
||||
float4x4 world = GetInstanceTransform(input);
|
||||
#else
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
float4x4 world = WorldMatrix;
|
||||
#endif
|
||||
float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||
float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -508,9 +508,9 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), world).xyz;
|
||||
#if PER_BONE_MOTION_BLUR
|
||||
float3 prevPosition = SkinPrevPosition(input);
|
||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), PrevWorldMatrix).xyz;
|
||||
#else
|
||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), PrevWorldMatrix).xyz;
|
||||
#endif
|
||||
|
||||
// Compute clip space position
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x3 WorldMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
float3 WorldInvScale;
|
||||
float WorldDeterminantSign;
|
||||
float PerInstanceRandom;
|
||||
@@ -194,7 +194,7 @@ float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||
{
|
||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
||||
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localVector, localToWorld);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
{
|
||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
||||
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localToWorld, worldVector);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
// Gets the current object position
|
||||
float3 GetObjectPosition(MaterialInput input)
|
||||
{
|
||||
return ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||
return WorldMatrix[3].xyz;
|
||||
}
|
||||
|
||||
// Gets the current object size
|
||||
@@ -365,8 +365,7 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
float3 position = float3(positionXZ.x, height, positionXZ.y);
|
||||
|
||||
// Compute world space vertex position
|
||||
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), worldMatrix).xyz;
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), WorldMatrix).xyz;
|
||||
|
||||
// Compute clip space position
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -390,7 +389,7 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
|
||||
// Compute world space normal vector
|
||||
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
output.Geometry.WorldNormal = tangentToWorld[2];
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 InverseViewProjectionMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
float4x3 WorldMatrixInverseTransposed;
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
float3 GridSize;
|
||||
float PerInstanceRandom;
|
||||
float Dummy0;
|
||||
@@ -49,7 +49,7 @@ struct MaterialInput
|
||||
#endif
|
||||
};
|
||||
|
||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
||||
#define GetInstanceTransform(input) WorldMatrix;
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
|
||||
@@ -170,12 +170,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
|
||||
float3 TransformParticlePosition(float3 input)
|
||||
{
|
||||
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||
return mul(float4(input, 1.0f), WorldMatrix).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
}
|
||||
|
||||
@8
|
||||
@@ -219,7 +219,7 @@ void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out fl
|
||||
materialInput.ParticleIndex = ParticleIndex;
|
||||
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
||||
materialInput.TwoSidedSign = 1.0f;
|
||||
materialInput.InstanceOrigin = ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||
materialInput.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
materialInput.InstanceParams = PerInstanceRandom;
|
||||
materialInput.SvPosition = clipPos;
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
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)
Normal file
BIN
Content/Engine/DefaultRadialMenu.flax
(Stored with Git LFS)
Normal file
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/Shaders/Editor/Grid.flax
(Stored with Git LFS)
Normal file
BIN
Content/Shaders/Editor/Grid.flax
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax
(Stored with Git LFS)
BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Lights.flax
(Stored with Git LFS)
BIN
Content/Shaders/Lights.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Quad.flax
(Stored with Git LFS)
BIN
Content/Shaders/Quad.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Shadows.flax
(Stored with Git LFS)
BIN
Content/Shaders/Shadows.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
Binary file not shown.
@@ -2,9 +2,9 @@
|
||||
"Name": "Flax",
|
||||
"Version": {
|
||||
"Major": 1,
|
||||
"Minor": 9,
|
||||
"Revision": 0,
|
||||
"Build": 6601
|
||||
"Minor": 8,
|
||||
"Revision": 2,
|
||||
"Build": 6512
|
||||
},
|
||||
"Company": "Flax",
|
||||
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
|
||||
@@ -13,6 +13,7 @@
|
||||
"Configuration": {
|
||||
"UseCSharp": true,
|
||||
"UseLargeWorlds": false,
|
||||
"UseDotNet": true
|
||||
"UseDotNet": true,
|
||||
"UseSDL": true
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,7 @@
|
||||
<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/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/=LO/@EntryIndexedValue">LO</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RPC/@EntryIndexedValue">RPC</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String>
|
||||
|
||||
@@ -61,6 +61,8 @@ namespace FlaxEditor.Content.GUI
|
||||
private bool _isRubberBandSpanning;
|
||||
private Float2 _mousePressLocation;
|
||||
private Rectangle _rubberBandRectangle;
|
||||
private bool _isCutting;
|
||||
private List<ContentItem> _cutItems = new List<ContentItem>();
|
||||
|
||||
private bool _validDragOver;
|
||||
private DragActors _dragActors;
|
||||
@@ -83,9 +85,9 @@ namespace FlaxEditor.Content.GUI
|
||||
public event Action<List<ContentItem>> OnDelete;
|
||||
|
||||
/// <summary>
|
||||
/// Called when user wants to paste the files/folders.
|
||||
/// Called when user wants to paste the files/folders. Bool is for cutting.
|
||||
/// </summary>
|
||||
public event Action<string[]> OnPaste;
|
||||
public event Action<string[], bool> OnPaste;
|
||||
|
||||
/// <summary>
|
||||
/// Called when user wants to duplicate the item(s).
|
||||
@@ -210,6 +212,12 @@ namespace FlaxEditor.Content.GUI
|
||||
}),
|
||||
new InputActionsContainer.Binding(options => options.Copy, Copy),
|
||||
new InputActionsContainer.Binding(options => options.Paste, Paste),
|
||||
new InputActionsContainer.Binding(options => options.Cut, Cut),
|
||||
new InputActionsContainer.Binding(options => options.Undo, () =>
|
||||
{
|
||||
if (_isCutting)
|
||||
UpdateContentItemCut(false);
|
||||
}),
|
||||
new InputActionsContainer.Binding(options => options.Duplicate, Duplicate),
|
||||
});
|
||||
}
|
||||
@@ -462,6 +470,7 @@ namespace FlaxEditor.Content.GUI
|
||||
/// </summary>
|
||||
public void Duplicate()
|
||||
{
|
||||
UpdateContentItemCut(false);
|
||||
OnDuplicate?.Invoke(_selection);
|
||||
}
|
||||
|
||||
@@ -475,6 +484,7 @@ namespace FlaxEditor.Content.GUI
|
||||
|
||||
var files = _selection.ConvertAll(x => x.Path).ToArray();
|
||||
Clipboard.Files = files;
|
||||
UpdateContentItemCut(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -496,7 +506,36 @@ namespace FlaxEditor.Content.GUI
|
||||
if (files == null || files.Length == 0)
|
||||
return;
|
||||
|
||||
OnPaste?.Invoke(files);
|
||||
OnPaste?.Invoke(files, _isCutting);
|
||||
UpdateContentItemCut(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cuts the items.
|
||||
/// </summary>
|
||||
public void Cut()
|
||||
{
|
||||
Copy();
|
||||
UpdateContentItemCut(true);
|
||||
}
|
||||
|
||||
private void UpdateContentItemCut(bool cut)
|
||||
{
|
||||
_isCutting = cut;
|
||||
|
||||
// Add selection to cut list
|
||||
if (cut)
|
||||
_cutItems.AddRange(_selection);
|
||||
|
||||
// Update item with if it is being cut.
|
||||
foreach (var item in _cutItems)
|
||||
{
|
||||
item.IsBeingCut = cut;
|
||||
}
|
||||
|
||||
// Clean up cut items
|
||||
if (!cut)
|
||||
_cutItems.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -58,10 +58,10 @@ namespace FlaxEngine.Tools
|
||||
FieldInfo[] fields = typeof(CustomMaxSizes).GetFields();
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
var field = fields[i];
|
||||
if (field.Name.Equals("value__"))
|
||||
var @field = fields[i];
|
||||
if (@field.Name.Equals("value__"))
|
||||
continue;
|
||||
if (value == (int)field.GetRawConstantValue())
|
||||
if (value == (int)@field.GetRawConstantValue())
|
||||
return (CustomMaxSizes)value;
|
||||
}
|
||||
return CustomMaxSizes._8192;
|
||||
|
||||
@@ -182,6 +182,11 @@ namespace FlaxEditor.Content
|
||||
/// </summary>
|
||||
public const int DefaultHeight = (DefaultThumbnailSize + 2 * DefaultMarginSize + DefaultTextHeight);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the item is being but.
|
||||
/// </summary>
|
||||
public bool IsBeingCut;
|
||||
|
||||
private ContentFolder _parentFolder;
|
||||
|
||||
private bool _isMouseDown;
|
||||
@@ -747,6 +752,12 @@ namespace FlaxEditor.Content
|
||||
Render2D.PushClip(ref textRect);
|
||||
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, 0.95f);
|
||||
Render2D.PopClip();
|
||||
|
||||
if (IsBeingCut)
|
||||
{
|
||||
var color = style.LightBackground.AlphaMultiplied(0.5f);
|
||||
Render2D.FillRectangle(clientRect, color);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -100,12 +100,16 @@ namespace FlaxEditor.Content
|
||||
/// <inheritdoc />
|
||||
public object GetValue(object obj)
|
||||
{
|
||||
if (!_type.Asset)
|
||||
throw new TargetException("Missing Visual Script asset.");
|
||||
return _type.Asset.GetScriptInstanceParameterValue(_parameter.Name, (Object)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetValue(object obj, object value)
|
||||
{
|
||||
if (!_type.Asset)
|
||||
throw new TargetException("Missing Visual Script asset.");
|
||||
_type.Asset.SetScriptInstanceParameterValue(_parameter.Name, (Object)obj, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +166,18 @@ namespace FlaxEditor.Content
|
||||
/// <inheritdoc />
|
||||
public override string Name { get; } = Utilities.Utils.GetPropertyNameUI(typeof(T).Name);
|
||||
|
||||
private SpriteHandle _thumbnail;
|
||||
|
||||
public SpawnableJsonAssetProxy()
|
||||
{
|
||||
_thumbnail = SpriteHandle.Invalid;
|
||||
}
|
||||
|
||||
public SpawnableJsonAssetProxy(SpriteHandle thumbnail)
|
||||
{
|
||||
_thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanCreate(ContentFolder targetLocation)
|
||||
{
|
||||
@@ -177,6 +189,12 @@ namespace FlaxEditor.Content
|
||||
{
|
||||
Editor.SaveJsonAsset(outputPath, new T());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
|
||||
{
|
||||
return _thumbnail.IsValid ? new JsonAssetItem(path, id, typeName, _thumbnail) : base.ConstructItem(path, typeName, ref id);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string TypeName { get; } = typeof(T).FullName;
|
||||
|
||||
@@ -365,7 +365,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
||||
Platform::CreateProcess(procSettings);
|
||||
}
|
||||
#endif
|
||||
const bool distributionPackage = buildSettings->ForDistribution;
|
||||
const bool distributionPackage = buildSettings->ForDistribution || data.Configuration == BuildConfiguration::Release;
|
||||
{
|
||||
CreateProcessSettings procSettings;
|
||||
procSettings.FileName = String::Format(TEXT("\"{0}\" {1}"), data.OriginalOutputPath / gradlew, distributionPackage ? TEXT("assemble") : TEXT("assembleDebug"));
|
||||
|
||||
@@ -111,6 +111,11 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
public PropertyNameLabel LinkedLabel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the layout for this editor. Used to calculate bounds.
|
||||
/// </summary>
|
||||
public LayoutElementsContainer Layout => _layout;
|
||||
|
||||
internal virtual void Initialize(CustomEditorPresenter presenter, LayoutElementsContainer layout, ValueContainer values)
|
||||
{
|
||||
_layout = layout;
|
||||
@@ -377,10 +382,6 @@ namespace FlaxEditor.CustomEditors
|
||||
else if (Values.HasDefaultValue && CanRevertDefaultValue)
|
||||
color = Color.Yellow * 0.8f;
|
||||
LinkedLabel.HighlightStripColor = color;
|
||||
|
||||
// Grey out deprecated members
|
||||
if (Values.IsObsolete)
|
||||
LinkedLabel.TextColor = LinkedLabel.TextColorHighlighted = FlaxEngine.GUI.Style.Current.ForegroundGrey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,13 +52,18 @@ namespace FlaxEditor.CustomEditors
|
||||
// Check if use provided editor
|
||||
if (overrideEditor != null)
|
||||
return overrideEditor;
|
||||
ScriptType targetType = values.Type;
|
||||
|
||||
// Special case if property is a pure object type and all values are the same type
|
||||
if (values.Type.Type == typeof(object) && values.Count > 0 && values[0] != null && !values.HasDifferentTypes)
|
||||
if (targetType.Type == typeof(object) && values.Count > 0 && values[0] != null && !values.HasDifferentTypes)
|
||||
return CreateEditor(TypeUtils.GetObjectType(values[0]), canUseRefPicker);
|
||||
|
||||
// Special case if property is interface but the value is implemented as Scripting Object that should use reference picker
|
||||
if (targetType.IsInterface && canUseRefPicker && values.Count > 0 && values[0] is FlaxEngine.Object)
|
||||
return new DummyEditor();
|
||||
|
||||
// Use editor for the property type
|
||||
return CreateEditor(values.Type, canUseRefPicker);
|
||||
return CreateEditor(targetType, canUseRefPicker);
|
||||
}
|
||||
|
||||
internal static CustomEditor CreateEditor(ScriptType targetType, bool canUseRefPicker = true)
|
||||
|
||||
@@ -67,19 +67,35 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
// Use default prefab instance as a reference for the editor
|
||||
Values.SetReferenceValue(prefabInstance);
|
||||
|
||||
// Add some UI
|
||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
||||
panel.CustomControl.Height = 20.0f;
|
||||
panel.CustomControl.SlotsVertically = 1;
|
||||
panel.CustomControl.SlotsHorizontally = 2;
|
||||
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
|
||||
{
|
||||
// Add some UI
|
||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
||||
panel.CustomControl.Height = 20.0f;
|
||||
panel.CustomControl.SlotsVertically = 1;
|
||||
panel.CustomControl.SlotsHorizontally = 3;
|
||||
|
||||
// Selecting actor prefab asset
|
||||
var selectPrefab = panel.Button("Select Prefab");
|
||||
selectPrefab.Button.Clicked += () =>
|
||||
{
|
||||
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
|
||||
Editor.Instance.Windows.ContentWin.Select(prefab);
|
||||
};
|
||||
|
||||
// Selecting actor prefab asset
|
||||
var selectPrefab = panel.Button("Select Prefab");
|
||||
selectPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Select(prefab);
|
||||
// Edit selected prefab asset
|
||||
var editPrefab = panel.Button("Edit Prefab");
|
||||
editPrefab.Button.Clicked += () =>
|
||||
{
|
||||
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
|
||||
Editor.Instance.Windows.ContentWin.Select(prefab);
|
||||
Editor.Instance.Windows.ContentWin.Open(Editor.Instance.Windows.ContentWin.View.Selection[0]);
|
||||
};
|
||||
|
||||
// Viewing changes applied to this actor
|
||||
var viewChanges = panel.Button("View Changes");
|
||||
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
||||
// Viewing changes applied to this actor
|
||||
var viewChanges = panel.Button("View Changes");
|
||||
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
||||
}
|
||||
|
||||
// Link event to update editor on prefab apply
|
||||
_linkedPrefabId = prefab.ID;
|
||||
|
||||
@@ -38,15 +38,15 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
_gizmoMode = new ClothPaintingGizmoMode();
|
||||
|
||||
var projectCache = Editor.Instance.ProjectCache;
|
||||
if (projectCache.TryGetCustomData("ClothGizmoPaintValue", out var cachedPaintValue))
|
||||
if (projectCache.TryGetCustomData("ClothGizmoPaintValue", out string cachedPaintValue))
|
||||
_gizmoMode.PaintValue = JsonSerializer.Deserialize<float>(cachedPaintValue);
|
||||
if (projectCache.TryGetCustomData("ClothGizmoContinuousPaint", out var cachedContinuousPaint))
|
||||
if (projectCache.TryGetCustomData("ClothGizmoContinuousPaint", out string cachedContinuousPaint))
|
||||
_gizmoMode.ContinuousPaint = JsonSerializer.Deserialize<bool>(cachedContinuousPaint);
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushFalloff", out var cachedBrushFalloff))
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushFalloff", out string cachedBrushFalloff))
|
||||
_gizmoMode.BrushFalloff = JsonSerializer.Deserialize<float>(cachedBrushFalloff);
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushSize", out var cachedBrushSize))
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushSize", out string cachedBrushSize))
|
||||
_gizmoMode.BrushSize = JsonSerializer.Deserialize<float>(cachedBrushSize);
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushStrength", out var cachedBrushStrength))
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushStrength", out string cachedBrushStrength))
|
||||
_gizmoMode.BrushStrength = JsonSerializer.Deserialize<float>(cachedBrushStrength);
|
||||
|
||||
gizmos.AddMode(_gizmoMode);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using FlaxEditor.Content.Settings;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -12,7 +13,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
[CustomEditor(typeof(LayersMask)), DefaultEditor]
|
||||
internal class LayersMaskEditor : CustomEditor
|
||||
{
|
||||
private CheckBox[] _checkBoxes;
|
||||
private List<CheckBox> _checkBoxes;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
@@ -24,16 +25,18 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
return;
|
||||
}
|
||||
|
||||
_checkBoxes = new CheckBox[layers.Length];
|
||||
_checkBoxes = new List<CheckBox>();
|
||||
for (int i = 0; i < layers.Length; i++)
|
||||
{
|
||||
var layer = layers[i];
|
||||
var property = layout.AddPropertyItem(layer);
|
||||
if (string.IsNullOrEmpty(layer))
|
||||
continue;
|
||||
var property = layout.AddPropertyItem($"{i}: {layer}");
|
||||
var checkbox = property.Checkbox().CheckBox;
|
||||
UpdateCheckbox(checkbox, i);
|
||||
checkbox.Tag = i;
|
||||
checkbox.StateChanged += OnCheckboxStateChanged;
|
||||
_checkBoxes[i] = checkbox;
|
||||
_checkBoxes.Add(checkbox);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,9 +53,9 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
{
|
||||
if (_checkBoxes != null)
|
||||
{
|
||||
for (int i = 0; i < _checkBoxes.Length; i++)
|
||||
for (int i = 0; i < _checkBoxes.Count; i++)
|
||||
{
|
||||
UpdateCheckbox(_checkBoxes[i], i);
|
||||
UpdateCheckbox(_checkBoxes[i], (int)_checkBoxes[i].Tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -880,6 +880,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
group.Panel.HeaderTextMargin = new Margin(scriptDrag.Right - 12, 15, 2, 2);
|
||||
group.Object(values, editor);
|
||||
// Remove drop down arrows and containment lines if no objects in the group
|
||||
if (group.Children.Count == 0)
|
||||
{
|
||||
group.Panel.ArrowImageOpened = null;
|
||||
group.Panel.ArrowImageClosed = null;
|
||||
group.Panel.EnableContainmentLines = false;
|
||||
}
|
||||
|
||||
// Scripts arrange bar
|
||||
dragBar = layout.Custom<ScriptArrangeBar>();
|
||||
|
||||
@@ -456,14 +456,57 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
for (int i = 0; i < layout.Children.Count; i++)
|
||||
{
|
||||
if (layout.Children[i] is GroupElement group && group.Panel.HeaderText == "Transform")
|
||||
if (layout.Children[i] is GroupElement group && group.Panel.HeaderText.Equals("Transform", StringComparison.Ordinal))
|
||||
{
|
||||
VerticalPanelElement mainHor = VerticalPanelWithoutMargin(group);
|
||||
CreateTransformElements(mainHor, ValuesTypes);
|
||||
group.ContainerControl.ChangeChildIndex(mainHor.Control, 0);
|
||||
layout.Children.Remove(group);
|
||||
layout.ContainerControl.Children.Remove(group.Panel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup transform
|
||||
if (Presenter is LayoutElementsContainer l)
|
||||
{
|
||||
for (int i = 0; i < l.Children.Count; i++)
|
||||
{
|
||||
if (l.Children[i] is GroupElement g && g.Panel.HeaderText.Equals("Transform", StringComparison.Ordinal))
|
||||
{
|
||||
l.Children.Remove(g);
|
||||
l.ContainerControl.Children.Remove(g.Panel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var transformGroup = l.Group("Transform");
|
||||
VerticalPanelElement mainHor = VerticalPanelWithoutMargin(transformGroup);
|
||||
CreateTransformElements(mainHor, ValuesTypes);
|
||||
|
||||
ScriptMemberInfo scaleInfo = ValuesTypes[0].GetProperty("Scale");
|
||||
ItemInfo scaleItem = new ItemInfo(scaleInfo);
|
||||
transformGroup.Property("Scale", scaleItem.GetValues(Values));
|
||||
|
||||
ScriptMemberInfo pivotInfo = ValuesTypes[0].GetProperty("Pivot");
|
||||
ItemInfo pivotItem = new ItemInfo(pivotInfo);
|
||||
transformGroup.Property("Pivot", pivotItem.GetValues(Values));
|
||||
|
||||
ScriptMemberInfo shearInfo = ValuesTypes[0].GetProperty("Shear");
|
||||
ItemInfo shearItem = new ItemInfo(shearInfo);
|
||||
transformGroup.Property("Shear", shearItem.GetValues(Values));
|
||||
|
||||
ScriptMemberInfo rotationInfo = ValuesTypes[0].GetProperty("Rotation");
|
||||
ItemInfo rotationItem = new ItemInfo(rotationInfo);
|
||||
transformGroup.Property("Rotation", rotationItem.GetValues(Values));
|
||||
|
||||
// Get position of general tab
|
||||
for (int i = 0; i < l.Children.Count; i++)
|
||||
{
|
||||
if (l.Children[i] is GroupElement g && g.Panel.HeaderText.Equals("General", StringComparison.Ordinal) && i + 1 <= l.Children.Count)
|
||||
{
|
||||
Presenter.ContainerControl.ChangeChildIndex(transformGroup.Control, i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateTransformElements(LayoutElementsContainer main, ScriptType[] valueTypes)
|
||||
@@ -645,7 +688,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
{
|
||||
var grid = UniformGridTwoByOne(el);
|
||||
grid.CustomControl.SlotPadding = new Margin(5, 5, 1, 1);
|
||||
var label = grid.Label(text);
|
||||
var label = grid.Label(text, TextAlignment.Far);
|
||||
var editor = grid.Object(values);
|
||||
if (editor is FloatEditor floatEditor && floatEditor.Element is FloatValueElement floatEditorElement)
|
||||
{
|
||||
|
||||
@@ -41,6 +41,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
base.Initialize(layout);
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
@@ -66,6 +73,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
base.Initialize(layout);
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
@@ -122,6 +136,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
menu.AddButton("Link", ToggleLink).LinkTooltip("Links scale components for uniform scaling");
|
||||
};
|
||||
}
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
|
||||
@@ -38,6 +38,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// </summary>
|
||||
public readonly int Index;
|
||||
|
||||
private Rectangle _arrangeButtonRect;
|
||||
private bool _arrangeButtonInUse;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CollectionItemLabel"/> class.
|
||||
/// </summary>
|
||||
@@ -50,6 +53,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Index = index;
|
||||
|
||||
SetupContextMenu += OnSetupContextMenu;
|
||||
_arrangeButtonRect = new Rectangle(2, 3, 12, 12);
|
||||
|
||||
// Extend margin of the label to support a dragging handle.
|
||||
Margin m = Margin;
|
||||
m.Left += 16;
|
||||
Margin = m;
|
||||
}
|
||||
|
||||
private void OnSetupContextMenu(PropertyNameLabel label, ContextMenu menu, CustomEditor linkedEditor)
|
||||
@@ -57,17 +66,119 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
menu.ItemsContainer.RemoveChildren();
|
||||
|
||||
menu.AddButton("Copy", linkedEditor.Copy);
|
||||
var paste = menu.AddButton("Paste", linkedEditor.Paste);
|
||||
paste.Enabled = linkedEditor.CanPaste;
|
||||
var b = menu.AddButton("Paste", linkedEditor.Paste);
|
||||
b.Enabled = linkedEditor.CanPaste && !Editor._readOnly;
|
||||
|
||||
menu.AddSeparator();
|
||||
var moveUpButton = menu.AddButton("Move up", OnMoveUpClicked);
|
||||
moveUpButton.Enabled = Index > 0;
|
||||
b = menu.AddButton("Move up", OnMoveUpClicked);
|
||||
b.Enabled = Index > 0 && !Editor._readOnly;
|
||||
|
||||
var moveDownButton = menu.AddButton("Move down", OnMoveDownClicked);
|
||||
moveDownButton.Enabled = Index + 1 < Editor.Count;
|
||||
b = menu.AddButton("Move down", OnMoveDownClicked);
|
||||
b.Enabled = Index + 1 < Editor.Count && !Editor._readOnly;
|
||||
|
||||
b = menu.AddButton("Remove", OnRemoveClicked);
|
||||
b.Enabled = !Editor._readOnly;
|
||||
}
|
||||
|
||||
menu.AddButton("Remove", OnRemoveClicked);
|
||||
/// <inheritdoc />
|
||||
public override void OnEndMouseCapture()
|
||||
{
|
||||
base.OnEndMouseCapture();
|
||||
|
||||
_arrangeButtonInUse = false;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw()
|
||||
{
|
||||
base.Draw();
|
||||
var style = FlaxEngine.GUI.Style.Current;
|
||||
|
||||
var mousePosition = PointFromScreen(Input.MouseScreenPosition);
|
||||
var dragBarColor = _arrangeButtonRect.Contains(mousePosition) ? style.Foreground : style.ForegroundGrey;
|
||||
Render2D.DrawSprite(FlaxEditor.Editor.Instance.Icons.DragBar12, _arrangeButtonRect, _arrangeButtonInUse ? Color.Orange : dragBarColor);
|
||||
if (_arrangeButtonInUse && ArrangeAreaCheck(out _, out var arrangeTargetRect))
|
||||
{
|
||||
Render2D.FillRectangle(arrangeTargetRect, style.Selection);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ArrangeAreaCheck(out int index, out Rectangle rect)
|
||||
{
|
||||
var child = Editor.ChildrenEditors[0];
|
||||
var container = child.Layout.ContainerControl;
|
||||
var mousePosition = container.PointFromScreen(Input.MouseScreenPosition);
|
||||
var barSidesExtend = 20.0f;
|
||||
var barHeight = 5.0f;
|
||||
var barCheckAreaHeight = 40.0f;
|
||||
var pos = mousePosition.Y + barCheckAreaHeight * 0.5f;
|
||||
|
||||
for (int i = 0; i < container.Children.Count / 2; i++)
|
||||
{
|
||||
var containerChild = container.Children[i * 2]; // times 2 to skip the value editor
|
||||
if (Mathf.IsInRange(pos, containerChild.Top, containerChild.Top + barCheckAreaHeight) || (i == 0 && pos < containerChild.Top))
|
||||
{
|
||||
index = i;
|
||||
var p1 = containerChild.UpperLeft;
|
||||
rect = new Rectangle(PointFromParent(p1) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var p2 = container.Children[((container.Children.Count / 2) - 1) * 2].BottomLeft;
|
||||
if (pos > p2.Y)
|
||||
{
|
||||
index = (container.Children.Count / 2) - 1;
|
||||
rect = new Rectangle(PointFromParent(p2) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
index = -1;
|
||||
rect = Rectangle.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
|
||||
{
|
||||
_arrangeButtonInUse = true;
|
||||
Focus();
|
||||
StartMouseCapture();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && _arrangeButtonInUse)
|
||||
{
|
||||
_arrangeButtonInUse = false;
|
||||
EndMouseCapture();
|
||||
if (ArrangeAreaCheck(out var index, out _))
|
||||
{
|
||||
Editor.Shift(Index, index);
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnMouseUp(location, button);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnLostFocus()
|
||||
{
|
||||
if (_arrangeButtonInUse)
|
||||
{
|
||||
_arrangeButtonInUse = false;
|
||||
EndMouseCapture();
|
||||
}
|
||||
|
||||
base.OnLostFocus();
|
||||
}
|
||||
|
||||
private void OnMoveUpClicked()
|
||||
@@ -105,6 +216,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
private bool _canReorder = true;
|
||||
|
||||
private Rectangle _arrangeButtonRect;
|
||||
private bool _arrangeButtonInUse;
|
||||
|
||||
public void Setup(CollectionEditor editor, int index, bool canReorder = true)
|
||||
{
|
||||
HeaderHeight = 18;
|
||||
@@ -122,10 +236,92 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
MouseButtonRightClicked += OnMouseButtonRightClicked;
|
||||
if (_canReorder)
|
||||
{
|
||||
// TODO: Drag drop
|
||||
HeaderTextMargin = new Margin(18, 0, 0, 0);
|
||||
_arrangeButtonRect = new Rectangle(16, 3, 12, 12);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ArrangeAreaCheck(out int index, out Rectangle rect)
|
||||
{
|
||||
var container = Parent;
|
||||
var mousePosition = container.PointFromScreen(Input.MouseScreenPosition);
|
||||
var barSidesExtend = 20.0f;
|
||||
var barHeight = 5.0f;
|
||||
var barCheckAreaHeight = 40.0f;
|
||||
var pos = mousePosition.Y + barCheckAreaHeight * 0.5f;
|
||||
|
||||
for (int i = 0; i < (container.Children.Count + 1) / 2; i++) // Add 1 to pretend there is a spacer at the end.
|
||||
{
|
||||
var containerChild = container.Children[i * 2]; // times 2 to skip the value editor
|
||||
if (Mathf.IsInRange(pos, containerChild.Top, containerChild.Top + barCheckAreaHeight) || (i == 0 && pos < containerChild.Top))
|
||||
{
|
||||
index = i;
|
||||
var p1 = containerChild.UpperLeft;
|
||||
rect = new Rectangle(PointFromParent(p1) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var p2 = container.Children[container.Children.Count - 1].BottomLeft;
|
||||
if (pos > p2.Y)
|
||||
{
|
||||
index = ((container.Children.Count + 1) / 2) - 1;
|
||||
rect = new Rectangle(PointFromParent(p2) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
index = -1;
|
||||
rect = Rectangle.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
base.Draw();
|
||||
if (_canReorder)
|
||||
{
|
||||
var style = FlaxEngine.GUI.Style.Current;
|
||||
|
||||
var mousePosition = PointFromScreen(Input.MouseScreenPosition);
|
||||
var dragBarColor = _arrangeButtonRect.Contains(mousePosition) ? style.Foreground : style.ForegroundGrey;
|
||||
Render2D.DrawSprite(FlaxEditor.Editor.Instance.Icons.DragBar12, _arrangeButtonRect, _arrangeButtonInUse ? Color.Orange : dragBarColor);
|
||||
if (_arrangeButtonInUse && ArrangeAreaCheck(out _, out var arrangeTargetRect))
|
||||
{
|
||||
Render2D.FillRectangle(arrangeTargetRect, style.Selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
|
||||
{
|
||||
_arrangeButtonInUse = true;
|
||||
Focus();
|
||||
StartMouseCapture();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && _arrangeButtonInUse)
|
||||
{
|
||||
_arrangeButtonInUse = false;
|
||||
EndMouseCapture();
|
||||
if (ArrangeAreaCheck(out var index, out _))
|
||||
{
|
||||
Editor.Shift(Index, index);
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnMouseUp(location, button);
|
||||
}
|
||||
|
||||
private void OnMouseButtonRightClicked(DropPanel panel, Float2 location)
|
||||
{
|
||||
if (LinkedEditor == null)
|
||||
@@ -177,6 +373,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
private IntValueBox _sizeBox;
|
||||
private Color _background;
|
||||
private int _elementsCount, _minCount, _maxCount;
|
||||
private bool _readOnly;
|
||||
private bool _canResize;
|
||||
private bool _canReorderItems;
|
||||
private CollectionAttribute.DisplayType _displayType;
|
||||
@@ -209,6 +406,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
return;
|
||||
|
||||
var size = Count;
|
||||
_readOnly = false;
|
||||
_canResize = true;
|
||||
_canReorderItems = true;
|
||||
_minCount = 0;
|
||||
@@ -224,7 +422,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
||||
if (collection != null)
|
||||
{
|
||||
_canResize = !collection.ReadOnly;
|
||||
_canResize = collection.CanResize;
|
||||
_readOnly = collection.ReadOnly;
|
||||
_minCount = collection.MinCount;
|
||||
_maxCount = collection.MaxCount;
|
||||
_canReorderItems = collection.CanReorderItems;
|
||||
@@ -235,6 +434,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
spacing = collection.Spacing;
|
||||
_displayType = collection.Display;
|
||||
}
|
||||
if (attributes != null && attributes.Any(x => x is ReadOnlyAttribute))
|
||||
{
|
||||
_readOnly = true;
|
||||
_canResize = false;
|
||||
_canReorderItems = false;
|
||||
}
|
||||
if (_maxCount == 0)
|
||||
_maxCount = ushort.MaxValue;
|
||||
_canResize &= _minCount < _maxCount;
|
||||
@@ -243,8 +448,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
dragArea.CustomControl.Editor = this;
|
||||
dragArea.CustomControl.ElementType = ElementType;
|
||||
|
||||
// Check for the AssetReferenceAttribute. In JSON assets, it can be used to filter
|
||||
// which scripts can be dragged over and dropped on this collection editor.
|
||||
// Check for the AssetReferenceAttribute. In JSON assets, it can be used to filter which scripts can be dragged over and dropped on this collection editor
|
||||
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
|
||||
if (assetReference != null)
|
||||
{
|
||||
@@ -315,7 +519,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
(elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) ||
|
||||
elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
|
||||
elementType.Equals(new ScriptType(typeof(SettingsBase)));
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
// Apply spacing
|
||||
@@ -333,6 +536,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var property = panel.AddPropertyItem(itemLabel);
|
||||
var itemLayout = (LayoutElementsContainer)property;
|
||||
itemLabel.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor);
|
||||
if (_readOnly && itemLayout.Children.Count > 0)
|
||||
GenericEditor.OnReadOnlyProperty(itemLayout);
|
||||
}
|
||||
else if (_displayType == CollectionAttribute.DisplayType.Header || (_displayType == CollectionAttribute.DisplayType.Default && !single))
|
||||
{
|
||||
@@ -340,13 +545,15 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
cdp.CustomControl.Setup(this, i, _canReorderItems);
|
||||
var itemLayout = cdp.VerticalPanel();
|
||||
cdp.CustomControl.LinkedEditor = itemLayout.Object(new ListValueContainer(elementType, i, Values, attributes), overrideEditor);
|
||||
if (_readOnly && itemLayout.Children.Count > 0)
|
||||
GenericEditor.OnReadOnlyProperty(itemLayout);
|
||||
}
|
||||
}
|
||||
}
|
||||
_elementsCount = size;
|
||||
|
||||
// Add/Remove buttons
|
||||
if (_canResize)
|
||||
if (_canResize && !_readOnly)
|
||||
{
|
||||
var panel = dragArea.HorizontalPanel();
|
||||
panel.Panel.Size = new Float2(0, 20);
|
||||
@@ -427,6 +634,39 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
SetValue(cloned);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shifts the specified item at the given index and moves it through the list to the other item. It supports undo.
|
||||
/// </summary>
|
||||
/// <param name="srcIndex">Index of the source item.</param>
|
||||
/// <param name="dstIndex">Index of the destination to move to.</param>
|
||||
private void Shift(int srcIndex, int dstIndex)
|
||||
{
|
||||
if (IsSetBlocked)
|
||||
return;
|
||||
|
||||
var cloned = CloneValues();
|
||||
if (dstIndex > srcIndex)
|
||||
{
|
||||
for (int i = srcIndex; i < dstIndex; i++)
|
||||
{
|
||||
var tmp = cloned[i + 1];
|
||||
cloned[i + 1] = cloned[i];
|
||||
cloned[i] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = srcIndex; i > dstIndex; i--)
|
||||
{
|
||||
var tmp = cloned[i - 1];
|
||||
cloned[i - 1] = cloned[i];
|
||||
cloned[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
SetValue(cloned);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the item at the specified index. It supports undo.
|
||||
/// </summary>
|
||||
|
||||
@@ -131,7 +131,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left)
|
||||
if (button == MouseButton.Left && _editor._canEditKeys)
|
||||
{
|
||||
OnEditClicked(null);
|
||||
return true;
|
||||
@@ -189,6 +189,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
||||
if (collection != null)
|
||||
{
|
||||
_canEditKeys &= collection.CanReorderItems;
|
||||
_readOnly = collection.ReadOnly;
|
||||
_notNullItems = collection.NotNullItems;
|
||||
if (collection.BackgroundColor.HasValue)
|
||||
@@ -197,6 +198,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
spacing = collection.Spacing;
|
||||
_displayType = collection.Display;
|
||||
}
|
||||
if (attributes != null && attributes.Any(x => x is ReadOnlyAttribute))
|
||||
{
|
||||
_readOnly = true;
|
||||
_canEditKeys = false;
|
||||
}
|
||||
|
||||
// Size
|
||||
if (layout.ContainerControl is DropPanel dropPanel)
|
||||
@@ -239,14 +245,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var keysEnumerable = ((IDictionary)Values[0]).Keys.OfType<object>();
|
||||
var keys = keysEnumerable as object[] ?? keysEnumerable.ToArray();
|
||||
var valuesType = new ScriptType(valueType);
|
||||
|
||||
bool single = valuesType.IsPrimitive ||
|
||||
valuesType.Equals(new ScriptType(typeof(string))) ||
|
||||
valuesType.IsEnum ||
|
||||
(valuesType.GetFields().Length == 1 && valuesType.GetProperties().Length == 0) ||
|
||||
(valuesType.GetProperties().Length == 1 && valuesType.GetFields().Length == 0) ||
|
||||
valuesType.Equals(new ScriptType(typeof(JsonAsset))) ||
|
||||
valuesType.Equals(new ScriptType(typeof(SettingsBase)));
|
||||
|
||||
// Use separate layout cells for each collection items to improve layout updates for them in separation
|
||||
var useSharedLayout = valueType.IsPrimitive || valueType.IsEnum;
|
||||
@@ -263,6 +261,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var property = panel.AddPropertyItem(new DictionaryItemLabel(this, key));
|
||||
var itemLayout = useSharedLayout ? (LayoutElementsContainer)property : property.VerticalPanel();
|
||||
itemLayout.Object(new DictionaryValueContainer(valuesType, key, Values), overrideEditor);
|
||||
if (_readOnly && itemLayout.Children.Count > 0)
|
||||
GenericEditor.OnReadOnlyProperty(itemLayout);
|
||||
}
|
||||
}
|
||||
_elementsCount = size;
|
||||
|
||||
17
Source/Editor/CustomEditors/Editors/DummyEditor.cs
Normal file
17
Source/Editor/CustomEditors/Editors/DummyEditor.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
internal sealed class DummyEditor : CustomEditor
|
||||
{
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
string valueName;
|
||||
if (Values.Count != 0 && Values[0] != null)
|
||||
valueName = Values[0].ToString();
|
||||
else
|
||||
valueName = "null";
|
||||
layout.Label($"{valueName} ({Values.Type})");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,7 +208,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
else
|
||||
{
|
||||
// Draw info
|
||||
Render2D.DrawText(style.FontMedium, "-", nameRect, isEnabled ? Color.OrangeRed : Color.DarkOrange, TextAlignment.Near, TextAlignment.Center);
|
||||
Render2D.DrawText(style.FontMedium, Type != null ? $"None ({Utilities.Utils.GetPropertyNameUI(Type.ToString())})" : "-", nameRect, isEnabled ? Color.OrangeRed : Color.DarkOrange, TextAlignment.Near, TextAlignment.Center);
|
||||
}
|
||||
|
||||
// Draw picker button
|
||||
|
||||
@@ -556,6 +556,43 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
return layout;
|
||||
}
|
||||
|
||||
internal static void OnReadOnlyProperty(LayoutElementsContainer itemLayout, int labelIndex = -1)
|
||||
{
|
||||
PropertiesListElement list = null;
|
||||
int firstChildControlIndex = 0;
|
||||
bool disableSingle = true;
|
||||
var control = itemLayout.Children[itemLayout.Children.Count - 1];
|
||||
if (control is GroupElement group && group.Children.Count > 0)
|
||||
{
|
||||
list = group.Children[0] as PropertiesListElement;
|
||||
disableSingle = false; // Disable all nested editors
|
||||
}
|
||||
else if (control is PropertiesListElement list1 && labelIndex != -1)
|
||||
{
|
||||
list = list1;
|
||||
firstChildControlIndex = list.Labels[labelIndex].FirstChildControlIndex;
|
||||
}
|
||||
else if (control?.Control != null)
|
||||
{
|
||||
control.Control.Enabled = false;
|
||||
}
|
||||
|
||||
if (list != null)
|
||||
{
|
||||
// Disable controls added to the editor
|
||||
var count = list.Properties.Children.Count;
|
||||
for (int j = firstChildControlIndex; j < count; j++)
|
||||
{
|
||||
var child = list.Properties.Children[j];
|
||||
if (disableSingle && child is PropertyNameLabel)
|
||||
break;
|
||||
|
||||
if (child != null)
|
||||
child.Enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluate the <see cref="VisibleIfAttribute"/> cache for a given property item.
|
||||
/// </summary>
|
||||
@@ -635,35 +672,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
if (item.IsReadOnly && itemLayout.Children.Count > 0)
|
||||
{
|
||||
PropertiesListElement list = null;
|
||||
int firstChildControlIndex = 0;
|
||||
bool disableSingle = true;
|
||||
var control = itemLayout.Children[itemLayout.Children.Count - 1];
|
||||
if (control is GroupElement group && group.Children.Count > 0)
|
||||
{
|
||||
list = group.Children[0] as PropertiesListElement;
|
||||
disableSingle = false; // Disable all nested editors
|
||||
}
|
||||
else if (control is PropertiesListElement list1)
|
||||
{
|
||||
list = list1;
|
||||
firstChildControlIndex = list.Labels[labelIndex].FirstChildControlIndex;
|
||||
}
|
||||
|
||||
if (list != null)
|
||||
{
|
||||
// Disable controls added to the editor
|
||||
var count = list.Properties.Children.Count;
|
||||
for (int j = firstChildControlIndex; j < count; j++)
|
||||
{
|
||||
var child = list.Properties.Children[j];
|
||||
if (disableSingle && child is PropertyNameLabel)
|
||||
break;
|
||||
|
||||
if (child != null)
|
||||
child.Enabled = false;
|
||||
}
|
||||
}
|
||||
OnReadOnlyProperty(itemLayout, labelIndex);
|
||||
}
|
||||
|
||||
EvaluateVisibleIf(itemLayout, item, labelIndex);
|
||||
|
||||
@@ -83,6 +83,22 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
_element.Value = asInt;
|
||||
else if (value is float asFloat)
|
||||
_element.Value = (int)asFloat;
|
||||
else if (value is double asDouble)
|
||||
_element.Value = (int)asDouble;
|
||||
else if (value is uint asUint)
|
||||
_element.Value = (int)asUint;
|
||||
else if (value is long asLong)
|
||||
_element.Value = (int)asLong;
|
||||
else if (value is ulong asULong)
|
||||
_element.Value = (int)asULong;
|
||||
else if (value is short asShort)
|
||||
_element.Value = asShort;
|
||||
else if (value is ushort asUshort)
|
||||
_element.Value = asUshort;
|
||||
else if (value is byte asByte)
|
||||
_element.Value = asByte;
|
||||
else if (value is sbyte asSbyte)
|
||||
_element.Value = asSbyte;
|
||||
else
|
||||
throw new Exception(string.Format("Invalid value type {0}.", value?.GetType().ToString() ?? "<null>"));
|
||||
}
|
||||
@@ -338,7 +354,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
protected abstract ulong GetValue(object value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value from long.
|
||||
/// Sets the value from long.
|
||||
/// </summary>
|
||||
/// <param name="value">The value from editor.</param>
|
||||
/// <returns>The value to object.</returns>
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (watermarkAttribute is WatermarkAttribute watermark)
|
||||
{
|
||||
_watermarkText = watermark.WatermarkText;
|
||||
var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGBA(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled;
|
||||
var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGB(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled;
|
||||
_watermarkColor = watermarkColor;
|
||||
_element.TextBox.WatermarkText = watermark.WatermarkText;
|
||||
_element.TextBox.WatermarkTextColor = watermarkColor;
|
||||
|
||||
@@ -242,7 +242,7 @@ namespace FlaxEditor.CustomEditors.GUI
|
||||
float namesWidth = _splitterValue * Width;
|
||||
int count = _element.Labels.Count;
|
||||
float[] yStarts = new float[count + 1];
|
||||
for (int i = 1; i < count; i++)
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var label = _element.Labels[i];
|
||||
|
||||
@@ -251,9 +251,13 @@ namespace FlaxEditor.CustomEditors.GUI
|
||||
else if (_children.Count <= label.FirstChildControlIndex)
|
||||
yStarts[i] = y;
|
||||
else
|
||||
{
|
||||
yStarts[i] = _children[label.FirstChildControlIndex].Top;
|
||||
if (i == count - 1)
|
||||
yStarts[i + 1] = _children[label.FirstChildControlIndex].Bottom;
|
||||
}
|
||||
|
||||
}
|
||||
yStarts[count] = y;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var label = _element.Labels[i];
|
||||
|
||||
@@ -318,7 +318,9 @@ namespace FlaxEditor.CustomEditors
|
||||
if (header.FontSize > 0)
|
||||
element.Label.Font = new FontReference(element.Label.Font.Font, header.FontSize);
|
||||
if (header.Color > 0)
|
||||
element.Label.TextColor = Color.FromRGBA(header.Color);
|
||||
element.Label.TextColor = Color.FromRGB(header.Color);
|
||||
var size = element.Label.Font.GetFont().MeasureText(header.Text);
|
||||
element.Label.Height = size.Y;
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,11 +139,6 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
public bool IsArray => Type != ScriptType.Null && Type.IsArray;
|
||||
|
||||
/// <summary>
|
||||
/// True if member or type has <see cref="System.ObsoleteAttribute"/> that marks it as obsolete.
|
||||
/// </summary>
|
||||
public bool IsObsolete { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values types array (without duplicates).
|
||||
/// </summary>
|
||||
@@ -165,7 +160,6 @@ namespace FlaxEditor.CustomEditors
|
||||
{
|
||||
Info = info;
|
||||
Type = Info.ValueType;
|
||||
IsObsolete = Info.HasAttribute(typeof(ObsoleteAttribute), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -247,6 +247,11 @@ namespace FlaxEditor
|
||||
/// </summary>
|
||||
public event Action PlayModeEnd;
|
||||
|
||||
/// <summary>
|
||||
/// Fired on Editor update
|
||||
/// </summary>
|
||||
public event Action EditorUpdate;
|
||||
|
||||
internal Editor()
|
||||
{
|
||||
Instance = this;
|
||||
@@ -330,7 +335,7 @@ namespace FlaxEditor
|
||||
}
|
||||
case GeneralOptions.StartupSceneModes.LastOpened:
|
||||
{
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName))
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
|
||||
{
|
||||
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
||||
foreach (var scene in lastScenes)
|
||||
@@ -442,7 +447,7 @@ namespace FlaxEditor
|
||||
}
|
||||
case GeneralOptions.StartupSceneModes.LastOpened:
|
||||
{
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName))
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
|
||||
{
|
||||
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
||||
foreach (var sceneId in lastScenes)
|
||||
@@ -459,7 +464,7 @@ namespace FlaxEditor
|
||||
}
|
||||
|
||||
// Restore view
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out var lastSceneSpawnName))
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out string lastSceneSpawnName))
|
||||
Windows.EditWin.Viewport.ViewRay = JsonSerializer.Deserialize<Ray>(lastSceneSpawnName);
|
||||
}
|
||||
break;
|
||||
@@ -485,6 +490,8 @@ namespace FlaxEditor
|
||||
{
|
||||
StateMachine.CurrentState.UpdateFPS();
|
||||
}
|
||||
|
||||
EditorUpdate?.Invoke();
|
||||
|
||||
// Update modules
|
||||
for (int i = 0; i < _modules.Count; i++)
|
||||
@@ -1364,6 +1371,7 @@ namespace FlaxEditor
|
||||
public byte AutoReloadScriptsOnMainWindowFocus;
|
||||
public byte ForceScriptCompilationOnStartup;
|
||||
public byte UseAssetImportPathRelative;
|
||||
public byte EnableParticlesPreview;
|
||||
public byte AutoRebuildCSG;
|
||||
public float AutoRebuildCSGTimeoutMs;
|
||||
public byte AutoRebuildNavMesh;
|
||||
|
||||
@@ -105,9 +105,9 @@ namespace FlaxEditor.GUI
|
||||
|
||||
private Rectangle Button1Rect => new Rectangle(Height + ButtonsOffset, 0, ButtonsSize, ButtonsSize);
|
||||
|
||||
private Rectangle Button2Rect => new Rectangle(Height + ButtonsOffset, ButtonsSize, ButtonsSize, ButtonsSize);
|
||||
private Rectangle Button2Rect => new Rectangle(Height + ButtonsOffset, ButtonsSize + 2, ButtonsSize, ButtonsSize);
|
||||
|
||||
private Rectangle Button3Rect => new Rectangle(Height + ButtonsOffset, ButtonsSize * 2, ButtonsSize, ButtonsSize);
|
||||
private Rectangle Button3Rect => new Rectangle(Height + ButtonsOffset, (ButtonsSize + 2) * 2, ButtonsSize, ButtonsSize);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw()
|
||||
@@ -149,6 +149,13 @@ namespace FlaxEditor.GUI
|
||||
style.Foreground,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
Render2D.DrawText(
|
||||
style.FontSmall,
|
||||
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
|
||||
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
|
||||
style.ForegroundGrey,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
}
|
||||
}
|
||||
// Check if has no item but has an asset (eg. virtual asset)
|
||||
@@ -171,6 +178,13 @@ namespace FlaxEditor.GUI
|
||||
style.Foreground,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
Render2D.DrawText(
|
||||
style.FontSmall,
|
||||
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
|
||||
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
|
||||
style.ForegroundGrey,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -178,6 +192,24 @@ namespace FlaxEditor.GUI
|
||||
// No element selected
|
||||
Render2D.FillRectangle(iconRect, style.BackgroundNormal);
|
||||
Render2D.DrawText(style.FontMedium, "No asset\nselected", iconRect, Color.Orange, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
|
||||
float sizeForTextLeft = Width - button1Rect.Right;
|
||||
if (sizeForTextLeft > 30)
|
||||
{
|
||||
Render2D.DrawText(
|
||||
style.FontSmall,
|
||||
$"None",
|
||||
new Rectangle(button1Rect.Right + 2, 0, sizeForTextLeft, ButtonsSize),
|
||||
style.Foreground,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
Render2D.DrawText(
|
||||
style.FontSmall,
|
||||
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
|
||||
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
|
||||
style.ForegroundGrey,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if drag is over
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace FlaxEditor.GUI
|
||||
{
|
||||
@@ -43,10 +44,20 @@ namespace FlaxEditor.GUI
|
||||
public Color TitleColor = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// The column title background background.
|
||||
/// The column title background color.
|
||||
/// </summary>
|
||||
public Color TitleBackgroundColor = Color.Brown;
|
||||
|
||||
/// <summary>
|
||||
/// The column title horizontal text alignment
|
||||
/// </summary>
|
||||
public TextAlignment TitleAlignment = TextAlignment.Near;
|
||||
|
||||
/// <summary>
|
||||
/// The column title margin.
|
||||
/// </summary>
|
||||
public Margin TitleMargin = new Margin(4, 4, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The minimum size (in pixels) of the column.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#define USE_IS_FOREGROUND
|
||||
#else
|
||||
#endif
|
||||
#if PLATFORM_SDL
|
||||
#define USE_SDL_WORKAROUNDS
|
||||
#endif
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
@@ -111,7 +114,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the empty menu popup o na screen.
|
||||
/// Shows the empty menu popup on a screen.
|
||||
/// </summary>
|
||||
/// <param name="control">The target control.</param>
|
||||
/// <param name="area">The target control area to cover.</param>
|
||||
@@ -215,7 +218,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
desc.AllowMaximize = false;
|
||||
desc.AllowDragAndDrop = false;
|
||||
desc.IsTopmost = true;
|
||||
desc.IsRegularWindow = false;
|
||||
desc.Type = WindowType.Utility;
|
||||
desc.HasSizingFrame = false;
|
||||
OnWindowCreating(ref desc);
|
||||
_window = Platform.CreateWindow(ref desc);
|
||||
@@ -228,8 +231,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
|
||||
// Show
|
||||
Visible = true;
|
||||
if (_window == null)
|
||||
return;
|
||||
_window.Show();
|
||||
PerformLayout();
|
||||
_previouslyFocused = parentWin.FocusedControl;
|
||||
@@ -378,6 +379,11 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_SDL_WORKAROUNDS
|
||||
private void OnWindowGotFocus()
|
||||
{
|
||||
}
|
||||
#else
|
||||
private void OnWindowGotFocus()
|
||||
{
|
||||
var child = _childCM;
|
||||
@@ -391,6 +397,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private void OnWindowLostFocus()
|
||||
{
|
||||
@@ -489,7 +496,12 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
// Let root context menu to check if none of the popup windows
|
||||
if (_parentCM == null && !IsForeground)
|
||||
{
|
||||
#if USE_SDL_WORKAROUNDS
|
||||
if (!IsMouseOver)
|
||||
Hide();
|
||||
#else
|
||||
Hide();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
private bool _disableEvents;
|
||||
private bool _useDynamicEditing;
|
||||
private bool _activeEyedropper;
|
||||
private bool _canPassLastChangeEvent = true;
|
||||
private ColorValueBox.ColorPickerEvent _onChanged;
|
||||
private ColorValueBox.ColorPickerClosedEvent _onClosed;
|
||||
|
||||
@@ -119,10 +120,8 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
_onClosed = pickerClosed;
|
||||
|
||||
// Get saved colors if they exist
|
||||
if (Editor.Instance.ProjectCache.TryGetCustomData("ColorPickerSavedColors", out var savedColors))
|
||||
{
|
||||
if (Editor.Instance.ProjectCache.TryGetCustomData("ColorPickerSavedColors", out string savedColors))
|
||||
_savedColors = JsonSerializer.Deserialize<List<Color>>(savedColors);
|
||||
}
|
||||
|
||||
// Selector
|
||||
_cSelector = new ColorSelectorWithSliders(180, 18)
|
||||
@@ -264,6 +263,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
Text = "+",
|
||||
Parent = this,
|
||||
TooltipText = "Save Color.",
|
||||
Tag = null,
|
||||
};
|
||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||
@@ -370,9 +370,25 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
Render2D.DrawText(style.FontMedium, "Hex", hex, textColor, TextAlignment.Near, TextAlignment.Center);
|
||||
|
||||
// Color difference
|
||||
var newRect = new Rectangle(_cOK.X, _cHex.Bottom + PickerMargin, _cCancel.Right - _cOK.Left, 0);
|
||||
newRect.Size.Y = _cValue.Bottom - newRect.Y;
|
||||
Render2D.FillRectangle(newRect, _value * _value.A);
|
||||
var newRect = new Rectangle(_cOK.X - 3, _cHex.Bottom + PickerMargin, 130, 0);
|
||||
newRect.Size.Y = 50;
|
||||
Render2D.FillRectangle(newRect, Color.White);
|
||||
var smallRectSize = 10;
|
||||
var numHor = Mathf.FloorToInt(newRect.Width / smallRectSize);
|
||||
var numVer = Mathf.FloorToInt(newRect.Height / smallRectSize);
|
||||
// Draw checkerboard for background of color to help with transparency
|
||||
for (int i = 0; i < numHor; i++)
|
||||
{
|
||||
for (int j = 0; j < numVer; j++)
|
||||
{
|
||||
if ((i + j) % 2 == 0)
|
||||
{
|
||||
var rect = new Rectangle(newRect.X + smallRectSize * i, newRect.Y + smallRectSize * j, new Float2(smallRectSize));
|
||||
Render2D.FillRectangle(rect, Color.Gray);
|
||||
}
|
||||
}
|
||||
}
|
||||
Render2D.FillRectangle(newRect, _value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -380,7 +396,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
// Auto cancel on lost focus
|
||||
#if !PLATFORM_LINUX
|
||||
((WindowRootControl)Root).Window.LostFocus += OnCancel;
|
||||
((WindowRootControl)Root).Window.LostFocus += OnWindowLostFocus;
|
||||
#endif
|
||||
|
||||
base.OnShow();
|
||||
@@ -489,7 +505,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
BackgroundColorHighlighted = savedColor,
|
||||
BackgroundColorSelected = savedColor.RGBMultiplied(0.8f),
|
||||
};
|
||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
|
||||
_savedColorButtons.Add(savedColorButton);
|
||||
}
|
||||
if (_savedColors.Count < 8)
|
||||
@@ -498,13 +514,27 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
Text = "+",
|
||||
Parent = this,
|
||||
TooltipText = "Save Color.",
|
||||
Tag = null,
|
||||
};
|
||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
|
||||
_savedColorButtons.Add(savedColorButton);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWindowLostFocus()
|
||||
{
|
||||
// Auto apply color on defocus
|
||||
var autoAcceptColorPickerChange = Editor.Instance.Options.Options.Interface.AutoAcceptColorPickerChange;
|
||||
if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent && autoAcceptColorPickerChange)
|
||||
{
|
||||
_canPassLastChangeEvent = false;
|
||||
_onChanged?.Invoke(_value, false);
|
||||
}
|
||||
|
||||
OnCancel();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSubmit()
|
||||
{
|
||||
@@ -529,8 +559,9 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
_disableEvents = true;
|
||||
|
||||
// Restore color if modified
|
||||
if (_useDynamicEditing && _initialValue != _value)
|
||||
if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent)
|
||||
{
|
||||
_canPassLastChangeEvent = false;
|
||||
_onChanged?.Invoke(_initialValue, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -311,7 +311,9 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
// Alpha
|
||||
float alphaY = _slider2Rect.Height * (1 - _color.A);
|
||||
var alphaR = new Rectangle(_slider2Rect.X - slidersOffset, _slider2Rect.Y + alphaY - slidersThickness / 2, _slider2Rect.Width + slidersOffset * 2, slidersThickness);
|
||||
Render2D.FillRectangle(_slider2Rect, _color, _color, Color.Transparent, Color.Transparent);
|
||||
var color = _color;
|
||||
color.A = 1; // Keep slider 2 fill rect from changing color alpha while selecting.
|
||||
Render2D.FillRectangle(_slider2Rect, color, color, Color.Transparent, Color.Transparent);
|
||||
Render2D.DrawRectangle(_slider2Rect, _isMouseDownSlider2 ? style.BackgroundSelected : Color.Black);
|
||||
Render2D.DrawRectangle(alphaR, _isMouseDownSlider2 ? Color.White : Color.Gray);
|
||||
}
|
||||
|
||||
@@ -67,9 +67,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
Proxy.Window.MouseUp += OnMouseUp;
|
||||
Proxy.Window.MouseMove += OnMouseMove;
|
||||
Proxy.Window.LostFocus += OnLostFocus;
|
||||
|
||||
// Start tracking mouse
|
||||
Proxy.Window.StartTrackingMouse(false);
|
||||
_toMove.Window.Window.MouseUp += OnMouseUp; // Intercept the drag release mouse event from source window
|
||||
|
||||
// Update window GUI
|
||||
Proxy.Window.GUI.PerformLayout();
|
||||
@@ -77,13 +75,16 @@ namespace FlaxEditor.GUI.Docking
|
||||
// Update rectangles
|
||||
UpdateRects();
|
||||
|
||||
// Hide base window
|
||||
window.Hide();
|
||||
|
||||
// Enable hit window presentation
|
||||
Proxy.Window.RenderingEnabled = true;
|
||||
Proxy.Window.Show();
|
||||
Proxy.Window.Focus();
|
||||
|
||||
// Hide base window
|
||||
window.Hide();
|
||||
|
||||
// Start tracking mouse
|
||||
Proxy.Window.StartTrackingMouse(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,6 +102,8 @@ namespace FlaxEditor.GUI.Docking
|
||||
Proxy.Window.MouseUp -= OnMouseUp;
|
||||
Proxy.Window.MouseMove -= OnMouseMove;
|
||||
Proxy.Window.LostFocus -= OnLostFocus;
|
||||
if (_toMove?.Window?.Window)
|
||||
_toMove.Window.Window.MouseUp -= OnMouseUp;
|
||||
|
||||
// Hide the proxy
|
||||
Proxy.Hide();
|
||||
@@ -438,7 +441,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
settings.AllowMinimize = false;
|
||||
settings.HasBorder = false;
|
||||
settings.HasSizingFrame = false;
|
||||
settings.IsRegularWindow = false;
|
||||
settings.Type = WindowType.Utility;
|
||||
settings.SupportsTransparency = true;
|
||||
settings.ShowInTaskbar = false;
|
||||
settings.ShowAfterFirstPaint = false;
|
||||
@@ -470,7 +473,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
settings.AllowMinimize = false;
|
||||
settings.HasBorder = false;
|
||||
settings.HasSizingFrame = false;
|
||||
settings.IsRegularWindow = false;
|
||||
settings.Type = WindowType.Utility;
|
||||
settings.SupportsTransparency = true;
|
||||
settings.ShowInTaskbar = false;
|
||||
settings.ActivateWhenFirstShown = false;
|
||||
|
||||
@@ -629,7 +629,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
|
||||
internal void MoveTabRight(int index)
|
||||
{
|
||||
if (index < _tabs.Count - 2)
|
||||
if (index < _tabs.Count - 1)
|
||||
{
|
||||
var tab = _tabs[index];
|
||||
_tabs.RemoveAt(index);
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
public DockWindow StartDragAsyncWindow;
|
||||
|
||||
private Rectangle HeaderRectangle => new Rectangle(0, 0, Width, DockPanel.DefaultHeaderHeight);
|
||||
private bool IsSingleFloatingWindow => _panel.TabsCount == 1 && _panel.IsFloating && _panel.ChildPanelsCount == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DockPanelProxy"/> class.
|
||||
@@ -187,6 +188,10 @@ namespace FlaxEditor.GUI.Docking
|
||||
var headerRect = HeaderRectangle;
|
||||
var tabsCount = _panel.TabsCount;
|
||||
|
||||
// Return and don't draw tab if only 1 window and it is floating
|
||||
if (IsSingleFloatingWindow)
|
||||
return;
|
||||
|
||||
// Check if has only one window docked
|
||||
if (tabsCount == 1)
|
||||
{
|
||||
@@ -321,6 +326,9 @@ namespace FlaxEditor.GUI.Docking
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||
{
|
||||
if (IsSingleFloatingWindow)
|
||||
return base.OnMouseDoubleClick(location, button);
|
||||
|
||||
// Maximize/restore on double click
|
||||
var tab = GetTabAtPos(location, out _);
|
||||
var rootWindow = tab?.RootWindow;
|
||||
@@ -339,6 +347,8 @@ namespace FlaxEditor.GUI.Docking
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
if (IsSingleFloatingWindow)
|
||||
return base.OnMouseDown(location, button);
|
||||
MouseDownWindow = GetTabAtPos(location, out IsMouseDownOverCross);
|
||||
|
||||
// Check buttons
|
||||
@@ -368,6 +378,9 @@ namespace FlaxEditor.GUI.Docking
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
if (IsSingleFloatingWindow)
|
||||
return base.OnMouseUp(location, button);
|
||||
|
||||
// Check tabs under mouse position at the beginning and at the end
|
||||
var tab = GetTabAtPos(location, out var overCross);
|
||||
|
||||
@@ -410,7 +423,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
public override void OnMouseMove(Float2 location)
|
||||
{
|
||||
MousePosition = location;
|
||||
if (IsMouseLeftButtonDown)
|
||||
if (IsMouseLeftButtonDown && !IsSingleFloatingWindow)
|
||||
{
|
||||
// Check if mouse is outside the header
|
||||
if (!HeaderRectangle.Contains(location))
|
||||
@@ -501,7 +514,10 @@ namespace FlaxEditor.GUI.Docking
|
||||
/// <inheritdoc />
|
||||
public override void GetDesireClientArea(out Rectangle rect)
|
||||
{
|
||||
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
|
||||
if (IsSingleFloatingWindow)
|
||||
rect = new Rectangle(0, 0, Width, Height);
|
||||
else
|
||||
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
|
||||
}
|
||||
|
||||
private DragDropEffect TrySelectTabUnderLocation(ref Float2 location)
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
settings.AllowMaximize = true;
|
||||
settings.AllowDragAndDrop = true;
|
||||
settings.IsTopmost = false;
|
||||
settings.IsRegularWindow = true;
|
||||
settings.Type = WindowType.Regular;
|
||||
settings.HasSizingFrame = true;
|
||||
settings.ShowAfterFirstPaint = false;
|
||||
settings.ShowInTaskbar = true;
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Input
|
||||
base.Draw();
|
||||
|
||||
var style = Style.Current;
|
||||
var r = new Rectangle(2, 2, Width - 4, Height - 4);
|
||||
var r = new Rectangle(0, 0, Width, Height);
|
||||
|
||||
Render2D.FillRectangle(r, _value);
|
||||
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
|
||||
|
||||
@@ -132,6 +132,8 @@ namespace FlaxEditor.GUI.Input
|
||||
_isSliding = false;
|
||||
EndMouseCapture();
|
||||
SlidingEnd?.Invoke();
|
||||
Defocus();
|
||||
Parent?.Focus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -183,6 +185,8 @@ namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
// Click change
|
||||
Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
|
||||
Defocus();
|
||||
Parent?.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +201,10 @@ namespace FlaxEditor.GUI.Input
|
||||
// Update sliding
|
||||
var slidePosition = location + Root.TrackingMouseOffset;
|
||||
Value = Mathf.Remap(slidePosition.X, 4, TrackSize - 4, Minimum, Maximum);
|
||||
if (Mathf.NearEqual(Value, Maximum))
|
||||
Value = Maximum;
|
||||
else if (Mathf.NearEqual(Value, Minimum))
|
||||
Value = Minimum;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -364,7 +372,7 @@ namespace FlaxEditor.GUI.Input
|
||||
};
|
||||
_slider.ValueChanged += SliderOnValueChanged;
|
||||
_slider.SlidingStart += SlidingStart;
|
||||
_slider.SlidingEnd += SlidingEnd;
|
||||
_slider.SlidingEnd += SliderOnSliderEnd;
|
||||
_textBox = new TextBox(false, split, 0)
|
||||
{
|
||||
Text = _value.ToString(CultureInfo.InvariantCulture),
|
||||
@@ -375,6 +383,13 @@ namespace FlaxEditor.GUI.Input
|
||||
_textBox.EditEnd += OnTextBoxEditEnd;
|
||||
}
|
||||
|
||||
private void SliderOnSliderEnd()
|
||||
{
|
||||
SlidingEnd?.Invoke();
|
||||
Defocus();
|
||||
Parent?.Focus();
|
||||
}
|
||||
|
||||
private void SliderOnValueChanged()
|
||||
{
|
||||
if (_valueIsChanging)
|
||||
@@ -397,6 +412,8 @@ namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
UpdateText();
|
||||
}
|
||||
Defocus();
|
||||
Parent?.Focus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -266,6 +266,7 @@ namespace FlaxEditor.GUI.Input
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
#if !PLATFORM_SDL
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMove(Float2 location)
|
||||
{
|
||||
@@ -292,6 +293,36 @@ namespace FlaxEditor.GUI.Input
|
||||
base.OnMouseMove(location);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMoveRelative(Float2 mouseMotion)
|
||||
{
|
||||
var location = Root.TrackingMouseOffset;
|
||||
if (_isSliding)
|
||||
{
|
||||
// Update sliding
|
||||
ApplySliding(Root.TrackingMouseOffset.X * _slideSpeed);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update cursor type so user knows they can slide value
|
||||
if (CanUseSliding && SlideRect.Contains(location) && !_isSliding)
|
||||
{
|
||||
Cursor = CursorType.SizeWE;
|
||||
_cursorChanged = true;
|
||||
}
|
||||
else if (_cursorChanged && !_isSliding)
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
_cursorChanged = false;
|
||||
}
|
||||
|
||||
base.OnMouseMoveRelative(mouseMotion);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
|
||||
@@ -23,6 +23,9 @@ namespace FlaxEditor.GUI
|
||||
[HideInEditor]
|
||||
public class Item : Control
|
||||
{
|
||||
private bool _isStartsWithMatch;
|
||||
private bool _isFullMatch;
|
||||
|
||||
/// <summary>
|
||||
/// The is mouse down flag.
|
||||
/// </summary>
|
||||
@@ -43,6 +46,11 @@ namespace FlaxEditor.GUI
|
||||
/// </summary>
|
||||
public string Category;
|
||||
|
||||
/// <summary>
|
||||
/// A computed score for the context menu order
|
||||
/// </summary>
|
||||
public float SortScore;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when items gets clicked by the user.
|
||||
/// </summary>
|
||||
@@ -61,44 +69,69 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the <see cref="SortScore"/>
|
||||
/// </summary>
|
||||
public void UpdateScore()
|
||||
{
|
||||
SortScore = 0;
|
||||
|
||||
if (!Visible)
|
||||
return;
|
||||
|
||||
if (_highlights is { Count: > 0 })
|
||||
SortScore += 1;
|
||||
if (_isStartsWithMatch)
|
||||
SortScore += 2;
|
||||
if (_isFullMatch)
|
||||
SortScore += 5;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the filter.
|
||||
/// </summary>
|
||||
/// <param name="filterText">The filter text.</param>
|
||||
public void UpdateFilter(string filterText)
|
||||
{
|
||||
_isStartsWithMatch = _isFullMatch = false;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(filterText))
|
||||
{
|
||||
// Clear filter
|
||||
_highlights?.Clear();
|
||||
Visible = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if (QueryFilterHelper.Match(filterText, Name, out var ranges))
|
||||
{
|
||||
if (QueryFilterHelper.Match(filterText, Name, out var ranges))
|
||||
{
|
||||
// Update highlights
|
||||
if (_highlights == null)
|
||||
_highlights = new List<Rectangle>(ranges.Length);
|
||||
else
|
||||
_highlights.Clear();
|
||||
var style = Style.Current;
|
||||
var font = style.FontSmall;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
{
|
||||
var start = font.GetCharPosition(Name, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
|
||||
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
|
||||
}
|
||||
Visible = true;
|
||||
}
|
||||
// Update highlights
|
||||
if (_highlights == null)
|
||||
_highlights = new List<Rectangle>(ranges.Length);
|
||||
else
|
||||
_highlights.Clear();
|
||||
var style = Style.Current;
|
||||
var font = style.FontSmall;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
{
|
||||
// Hide
|
||||
_highlights?.Clear();
|
||||
Visible = false;
|
||||
var start = font.GetCharPosition(Name, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
|
||||
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
|
||||
|
||||
if (ranges[i].StartIndex <= 0)
|
||||
{
|
||||
_isStartsWithMatch = true;
|
||||
if (ranges[i].Length == Name.Length)
|
||||
_isFullMatch = true;
|
||||
}
|
||||
}
|
||||
Visible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide
|
||||
_highlights?.Clear();
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -178,7 +211,14 @@ namespace FlaxEditor.GUI
|
||||
public override int Compare(Control other)
|
||||
{
|
||||
if (other is Item otherItem)
|
||||
return string.Compare(Name, otherItem.Name, StringComparison.Ordinal);
|
||||
{
|
||||
int order = -1 * SortScore.CompareTo(otherItem.SortScore);
|
||||
if (order == 0)
|
||||
{
|
||||
order = string.Compare(Name, otherItem.Name, StringComparison.Ordinal);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
return base.Compare(other);
|
||||
}
|
||||
}
|
||||
@@ -249,7 +289,10 @@ namespace FlaxEditor.GUI
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
if (items[i] is Item item)
|
||||
{
|
||||
item.UpdateFilter(_searchBox.Text);
|
||||
item.UpdateScore();
|
||||
}
|
||||
}
|
||||
if (_categoryPanels != null)
|
||||
{
|
||||
@@ -262,6 +305,7 @@ namespace FlaxEditor.GUI
|
||||
if (category.Children[j] is Item item2)
|
||||
{
|
||||
item2.UpdateFilter(_searchBox.Text);
|
||||
item2.UpdateScore();
|
||||
anyVisible |= item2.Visible;
|
||||
}
|
||||
}
|
||||
@@ -273,6 +317,8 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
}
|
||||
|
||||
SortItems();
|
||||
|
||||
UnlockChildrenRecursive();
|
||||
PerformLayout(true);
|
||||
_searchBox.Focus();
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace FlaxEditor.GUI
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
public sealed class MainMenu : ContainerControl
|
||||
{
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
private bool _useCustomWindowSystem;
|
||||
private Image _icon;
|
||||
private Label _title;
|
||||
@@ -67,7 +67,7 @@ namespace FlaxEditor.GUI
|
||||
AutoFocus = false;
|
||||
AnchorPreset = AnchorPresets.HorizontalStretchTop;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
_useCustomWindowSystem = !Editor.Instance.Options.Options.Interface.UseNativeWindowSystem;
|
||||
if (_useCustomWindowSystem)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
/// <inheritdoc />
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
@@ -291,7 +291,7 @@ namespace FlaxEditor.GUI
|
||||
if (base.OnMouseDoubleClick(location, button))
|
||||
return true;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
var child = GetChildAtRecursive(location);
|
||||
if (_useCustomWindowSystem && child is not Button && child is not MainMenuButton)
|
||||
{
|
||||
@@ -321,7 +321,7 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
float x = 0;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
if (_useCustomWindowSystem)
|
||||
{
|
||||
// Icon
|
||||
@@ -349,7 +349,7 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
if (_useCustomWindowSystem)
|
||||
{
|
||||
// Buttons
|
||||
@@ -367,7 +367,7 @@ namespace FlaxEditor.GUI
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace FlaxEditor.GUI
|
||||
Text = text;
|
||||
|
||||
var style = Style.Current;
|
||||
#if PLATFORM_WINDOWS
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
if (Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
|
||||
{
|
||||
BackgroundColorMouseOver = style.BackgroundHighlighted;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace FlaxEditor.GUI
|
||||
ContentItem = item;
|
||||
ContentItem.AddReference(this);
|
||||
|
||||
Name = item.ShortName;
|
||||
OnItemRenamed(item);
|
||||
TooltipText = item.Path;
|
||||
|
||||
Height = IconSize + 4;
|
||||
@@ -82,7 +82,9 @@ namespace FlaxEditor.GUI
|
||||
/// <inheritdoc />
|
||||
public void OnItemRenamed(ContentItem item)
|
||||
{
|
||||
Name = ContentItem.ShortName;
|
||||
Name = item.ShortName;
|
||||
if (item is ScriptItem)
|
||||
Name = item.FileName; // Show extension for scripts (esp. for .h and .cpp files of the same name)
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -130,12 +130,14 @@ namespace FlaxEditor.GUI
|
||||
|
||||
var style = Style.Current;
|
||||
var font = column.TitleFont ?? style.FontMedium;
|
||||
Render2D.DrawText(font, column.Title, rect, column.TitleColor, TextAlignment.Center, TextAlignment.Center);
|
||||
var textRect = rect;
|
||||
column.TitleMargin.ShrinkRectangle(ref textRect);
|
||||
Render2D.DrawText(font, column.Title, textRect, column.TitleColor, column.TitleAlignment, TextAlignment.Center);
|
||||
|
||||
if (columnIndex < _columns.Length - 1)
|
||||
{
|
||||
var splitRect = new Rectangle(rect.Right - 1, 2, 2, rect.Height - 4);
|
||||
Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : column.TitleBackgroundColor * 0.9f);
|
||||
var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
|
||||
Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : style.Background * 0.9f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +153,7 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
rect.Width = GetColumnWidth(i);
|
||||
|
||||
var splitRect = new Rectangle(rect.Right - 1, 2, 2, rect.Height - 4);
|
||||
var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
|
||||
if (splitRect.Contains(location))
|
||||
{
|
||||
// Start moving splitter
|
||||
@@ -193,6 +195,31 @@ namespace FlaxEditor.GUI
|
||||
|
||||
PerformLayout();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_columns != null && _splits != null)
|
||||
{
|
||||
Rectangle rect = new Rectangle(0, 0, 0, _headerHeight);
|
||||
for (int i = 0; i < _columns.Length - 1; i++)
|
||||
{
|
||||
rect.Width = GetColumnWidth(i);
|
||||
|
||||
var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
|
||||
if (splitRect.Contains(location))
|
||||
{
|
||||
// Start moving splitter
|
||||
Cursor = CursorType.SizeWE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
}
|
||||
|
||||
rect.X += rect.Width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnMouseMove(location);
|
||||
}
|
||||
|
||||
@@ -418,9 +418,19 @@ namespace FlaxEditor.GUI.Tabs
|
||||
{
|
||||
// If scroll bar is visible it covers part of the tab header so include this in tab size to improve usability
|
||||
if (_orientation == Orientation.Horizontal && TabsPanel.HScrollBar.Visible)
|
||||
{
|
||||
tabsSize.Y += TabsPanel.HScrollBar.Height;
|
||||
var style = Style.Current;
|
||||
TabsPanel.HScrollBar.TrackColor = style.Background;
|
||||
TabsPanel.HScrollBar.ThumbColor = style.ForegroundGrey;
|
||||
}
|
||||
else if (_orientation == Orientation.Vertical && TabsPanel.VScrollBar.Visible)
|
||||
{
|
||||
tabsSize.X += TabsPanel.VScrollBar.Width;
|
||||
var style = Style.Current;
|
||||
TabsPanel.VScrollBar.TrackColor = style.Background;
|
||||
TabsPanel.VScrollBar.ThumbColor = style.ForegroundGrey;
|
||||
}
|
||||
}
|
||||
|
||||
// Fit the tabs panel
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
/// The keyframes.
|
||||
/// </summary>
|
||||
[EditorDisplay("Keyframes", EditorDisplayAttribute.InlineStyle), ExpandGroups]
|
||||
[Collection(CanReorderItems = false, ReadOnly = true)]
|
||||
[Collection(CanReorderItems = false, CanResize = true)]
|
||||
public List<KeyValuePair<string, object>> Keyframes;
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
/// The parameters values.
|
||||
/// </summary>
|
||||
[EditorDisplay("Parameters", EditorDisplayAttribute.InlineStyle), ExpandGroups]
|
||||
[Collection(CanReorderItems = false, ReadOnly = true)]
|
||||
[Collection(CanReorderItems = false, CanResize = true)]
|
||||
public object[] Parameters;
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -363,6 +363,8 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
if (_previewValue != null)
|
||||
Timeline.ShowPreviewValuesChanged -= OnTimelineShowPreviewValuesChanged;
|
||||
_previewValue = null;
|
||||
_rightKey = null;
|
||||
_addKey = null;
|
||||
|
||||
@@ -698,6 +698,38 @@ namespace FlaxEditor.GUI.Tree
|
||||
}
|
||||
}
|
||||
|
||||
// Show tree guidelines
|
||||
if (Editor.Instance.Options.Options.Interface.ShowTreeLines)
|
||||
{
|
||||
TreeNode parentNode = Parent as TreeNode;
|
||||
bool thisNodeIsLast = false;
|
||||
while (parentNode != null && parentNode != ParentTree.Children[0])
|
||||
{
|
||||
float bottomOffset = 0;
|
||||
float topOffset = 0;
|
||||
|
||||
if (Parent == parentNode && this == Parent.Children[0])
|
||||
topOffset = 2;
|
||||
|
||||
if (thisNodeIsLast && parentNode.Children.Count == 1)
|
||||
bottomOffset = topOffset != 0 ? 4 : 2;
|
||||
|
||||
if (Parent == parentNode && this == Parent.Children[Parent.Children.Count - 1] && !_opened)
|
||||
{
|
||||
thisNodeIsLast = true;
|
||||
bottomOffset = topOffset != 0 ? 4 : 2;
|
||||
}
|
||||
|
||||
float leftOffset = 9;
|
||||
// Adjust offset for icon image
|
||||
if (_iconCollaped.IsValid)
|
||||
leftOffset += 18;
|
||||
var lineRect1 = new Rectangle(parentNode.TextRect.Left - leftOffset, parentNode.HeaderRect.Top + topOffset, 1, parentNode.HeaderRect.Height - bottomOffset);
|
||||
Render2D.FillRectangle(lineRect1, isSelected ? style.ForegroundGrey : style.LightBackground);
|
||||
parentNode = parentNode.Parent as TreeNode;
|
||||
}
|
||||
}
|
||||
|
||||
// Base
|
||||
if (_opened)
|
||||
{
|
||||
@@ -721,15 +753,16 @@ namespace FlaxEditor.GUI.Tree
|
||||
var children = _children;
|
||||
if (children.Count == 0)
|
||||
return;
|
||||
var last = children.Count - 1;
|
||||
|
||||
if (CullChildren)
|
||||
{
|
||||
Render2D.PeekClip(out var globalClipping);
|
||||
Render2D.PeekTransform(out var globalTransform);
|
||||
|
||||
// Try to estimate the rough location of the first node, assuming the node height is constant
|
||||
// Try to estimate the rough location of the first and the last nodes, assuming the node height is constant
|
||||
var firstChildGlobalRect = GetChildGlobalRectangle(children[0], ref globalTransform);
|
||||
var firstVisibleChild = Math.Clamp((int)Math.Floor((globalClipping.Y - firstChildGlobalRect.Top) / firstChildGlobalRect.Height) + 1, 0, children.Count - 1);
|
||||
var firstVisibleChild = Math.Clamp((int)Math.Floor((globalClipping.Top - firstChildGlobalRect.Top) / _headerHeight) + 1, 0, last);
|
||||
if (GetChildGlobalRectangle(children[firstVisibleChild], ref globalTransform).Top > globalClipping.Top || !children[firstVisibleChild].Visible)
|
||||
{
|
||||
// Estimate overshoot, either it's partially visible or hidden in the tree
|
||||
@@ -738,22 +771,29 @@ namespace FlaxEditor.GUI.Tree
|
||||
var child = children[firstVisibleChild];
|
||||
if (!child.Visible)
|
||||
continue;
|
||||
|
||||
if (GetChildGlobalRectangle(child, ref globalTransform).Top < globalClipping.Top)
|
||||
break;
|
||||
}
|
||||
}
|
||||
var lastVisibleChild = Math.Clamp((int)Math.Ceiling((globalClipping.Bottom - firstChildGlobalRect.Top) / _headerHeight) + 1, firstVisibleChild, last);
|
||||
if (GetChildGlobalRectangle(children[lastVisibleChild], ref globalTransform).Top < globalClipping.Bottom || !children[lastVisibleChild].Visible)
|
||||
{
|
||||
// Estimate overshoot, either it's partially visible or hidden in the tree
|
||||
for (; lastVisibleChild < last; lastVisibleChild++)
|
||||
{
|
||||
var child = children[lastVisibleChild];
|
||||
if (!child.Visible)
|
||||
continue;
|
||||
if (GetChildGlobalRectangle(child, ref globalTransform).Top > globalClipping.Bottom)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = firstVisibleChild; i < children.Count; i++)
|
||||
for (int i = firstVisibleChild; i <= lastVisibleChild; i++)
|
||||
{
|
||||
var child = children[i];
|
||||
if (!child.Visible)
|
||||
continue;
|
||||
|
||||
var childGlobalRect = GetChildGlobalRectangle(child, ref globalTransform);
|
||||
if (!globalClipping.Intersects(ref childGlobalRect))
|
||||
break;
|
||||
|
||||
Render2D.PushTransform(ref child._cachedTransform);
|
||||
child.Draw();
|
||||
Render2D.PopTransform();
|
||||
@@ -767,7 +807,7 @@ namespace FlaxEditor.GUI.Tree
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < children.Count; i++)
|
||||
for (int i = 0; i <= last; i++)
|
||||
{
|
||||
var child = children[i];
|
||||
if (child.Visible)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using FlaxEngine;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace FlaxEditor.Gizmo
|
||||
{
|
||||
@@ -15,91 +16,120 @@ namespace FlaxEditor.Gizmo
|
||||
[HideInEditor]
|
||||
private sealed class Renderer : PostProcessEffect
|
||||
{
|
||||
private IntPtr _debugDrawContext;
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct Data
|
||||
{
|
||||
public Matrix WorldMatrix;
|
||||
public Matrix ViewProjectionMatrix;
|
||||
public Float4 GridColor;
|
||||
public Float3 ViewPos;
|
||||
public float Far;
|
||||
public Float3 Padding;
|
||||
public float GridSize;
|
||||
}
|
||||
|
||||
private static readonly uint[] _triangles =
|
||||
{
|
||||
0, 2, 1, // Face front
|
||||
1, 3, 0,
|
||||
};
|
||||
|
||||
private GPUBuffer[] _vbs = new GPUBuffer[1];
|
||||
private GPUBuffer _vertexBuffer;
|
||||
private GPUBuffer _indexBuffer;
|
||||
private GPUPipelineState _psGrid;
|
||||
private Shader _shader;
|
||||
|
||||
public Renderer()
|
||||
{
|
||||
Order = -100;
|
||||
UseSingleTarget = true;
|
||||
Location = PostProcessEffectLocation.BeforeForwardPass;
|
||||
Location = PostProcessEffectLocation.Default;
|
||||
_shader = FlaxEngine.Content.LoadAsyncInternal<Shader>("Shaders/Editor/Grid");
|
||||
}
|
||||
|
||||
~Renderer()
|
||||
{
|
||||
if (_debugDrawContext != IntPtr.Zero)
|
||||
{
|
||||
DebugDraw.FreeContext(_debugDrawContext);
|
||||
_debugDrawContext = IntPtr.Zero;
|
||||
}
|
||||
Destroy(ref _psGrid);
|
||||
Destroy(ref _vertexBuffer);
|
||||
Destroy(ref _indexBuffer);
|
||||
_shader = null;
|
||||
}
|
||||
|
||||
public override void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
||||
public override unsafe void Render(GPUContext context, ref RenderContext renderContext, GPUTexture input, GPUTexture output)
|
||||
{
|
||||
if (_shader == null)
|
||||
return;
|
||||
Profiler.BeginEventGPU("Editor Grid");
|
||||
|
||||
if (_debugDrawContext == IntPtr.Zero)
|
||||
_debugDrawContext = DebugDraw.AllocateContext();
|
||||
DebugDraw.SetContext(_debugDrawContext);
|
||||
DebugDraw.UpdateContext(_debugDrawContext, 1.0f / Mathf.Max(Engine.FramesPerSecond, 1));
|
||||
|
||||
var viewPos = (Vector3)renderContext.View.Position;
|
||||
var plane = new Plane(Vector3.Zero, Vector3.UnitY);
|
||||
var dst = CollisionsHelper.DistancePlanePoint(ref plane, ref viewPos);
|
||||
|
||||
var options = Editor.Instance.Options.Options;
|
||||
float space = options.Viewport.ViewportGridScale, size;
|
||||
if (dst <= 500.0f)
|
||||
Float3 camPos = renderContext.View.WorldPosition;
|
||||
float gridSize = renderContext.View.Far + 20000;
|
||||
|
||||
// Lazy-init resources
|
||||
if (_vertexBuffer == null)
|
||||
{
|
||||
size = 8000;
|
||||
_vertexBuffer = new GPUBuffer();
|
||||
var desc = GPUBufferDescription.Vertex(sizeof(Float3), 4);
|
||||
_vertexBuffer.Init(ref desc);
|
||||
}
|
||||
else if (dst <= 2000.0f)
|
||||
if (_indexBuffer == null)
|
||||
{
|
||||
space *= 2;
|
||||
size = 8000;
|
||||
_indexBuffer = new GPUBuffer();
|
||||
fixed (uint* ptr = _triangles)
|
||||
{
|
||||
var desc = GPUBufferDescription.Index(sizeof(uint), _triangles.Length, new IntPtr(ptr));
|
||||
_indexBuffer.Init(ref desc);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (_psGrid == null)
|
||||
{
|
||||
space *= 20;
|
||||
size = 100000;
|
||||
_psGrid = new GPUPipelineState();
|
||||
var desc = GPUPipelineState.Description.Default;
|
||||
desc.BlendMode = BlendingMode.AlphaBlend;
|
||||
desc.CullMode = CullMode.TwoSided;
|
||||
desc.VS = _shader.GPU.GetVS("VS_Grid");
|
||||
desc.PS = _shader.GPU.GetPS("PS_Grid");
|
||||
_psGrid.Init(ref desc);
|
||||
}
|
||||
|
||||
float bigLineIntensity = 0.8f;
|
||||
Color bigColor = Color.Gray * bigLineIntensity;
|
||||
Color color = bigColor * 0.8f;
|
||||
int count = (int)(size / space);
|
||||
int midLine = count / 2;
|
||||
int bigLinesMod = count / 8;
|
||||
|
||||
Vector3 start = new Vector3(0, 0, size * -0.5f);
|
||||
Vector3 end = new Vector3(0, 0, size * 0.5f);
|
||||
|
||||
for (int i = 0; i <= count; i++)
|
||||
// Update vertices of the plane
|
||||
// TODO: perf this operation in a Vertex Shader
|
||||
float y = 1.5f; // Add small bias to reduce Z-fighting with geometry at scene origin
|
||||
var vertices = new Float3[]
|
||||
{
|
||||
start.X = end.X = i * space + start.Z;
|
||||
Color lineColor = color;
|
||||
if (i == midLine)
|
||||
lineColor = Color.Blue * bigLineIntensity;
|
||||
else if (i % bigLinesMod == 0)
|
||||
lineColor = bigColor;
|
||||
DebugDraw.DrawLine(start, end, lineColor);
|
||||
new Float3(-gridSize + camPos.X, y, -gridSize + camPos.Z),
|
||||
new Float3(gridSize + camPos.X, y, gridSize + camPos.Z),
|
||||
new Float3(-gridSize + camPos.X, y, gridSize + camPos.Z),
|
||||
new Float3(gridSize + camPos.X, y, -gridSize + camPos.Z),
|
||||
};
|
||||
fixed (Float3* ptr = vertices)
|
||||
{
|
||||
context.UpdateBuffer(_vertexBuffer, new IntPtr(ptr), (uint)(sizeof(Float3) * vertices.Length));
|
||||
}
|
||||
|
||||
start = new Vector3(size * -0.5f, 0, 0);
|
||||
end = new Vector3(size * 0.5f, 0, 0);
|
||||
|
||||
for (int i = 0; i <= count; i++)
|
||||
// Update constant buffer data
|
||||
var cb = _shader.GPU.GetCB(0);
|
||||
if (cb != IntPtr.Zero)
|
||||
{
|
||||
start.Z = end.Z = i * space + start.X;
|
||||
Color lineColor = color;
|
||||
if (i == midLine)
|
||||
lineColor = Color.Red * bigLineIntensity;
|
||||
else if (i % bigLinesMod == 0)
|
||||
lineColor = bigColor;
|
||||
DebugDraw.DrawLine(start, end, lineColor);
|
||||
var data = new Data();
|
||||
Matrix.Multiply(ref renderContext.View.View, ref renderContext.View.Projection, out var viewProjection);
|
||||
data.WorldMatrix = Matrix.Identity;
|
||||
Matrix.Transpose(ref viewProjection, out data.ViewProjectionMatrix);
|
||||
data.ViewPos = renderContext.View.WorldPosition;
|
||||
data.GridColor = options.Viewport.ViewportGridColor;
|
||||
data.Far = renderContext.View.Far;
|
||||
data.GridSize = options.Viewport.ViewportGridViewDistance;
|
||||
context.UpdateCB(cb, new IntPtr(&data));
|
||||
}
|
||||
|
||||
DebugDraw.Draw(ref renderContext, input.View(), null, true);
|
||||
DebugDraw.SetContext(IntPtr.Zero);
|
||||
// Draw geometry using custom Pixel Shader and Vertex Shader
|
||||
context.BindCB(0, cb);
|
||||
context.BindIB(_indexBuffer);
|
||||
_vbs[0] = _vertexBuffer;
|
||||
context.BindVB(_vbs);
|
||||
context.SetState(_psGrid);
|
||||
context.SetRenderTarget(renderContext.Buffers.DepthBuffer.View(), input.View());
|
||||
context.DrawIndexed((uint)_triangles.Length);
|
||||
|
||||
Profiler.EndEventGPU();
|
||||
}
|
||||
|
||||
@@ -253,7 +253,11 @@ namespace FlaxEditor
|
||||
{
|
||||
// Select node (with additive mode)
|
||||
var selection = new List<SceneGraphNode>();
|
||||
if (Root.GetKey(KeyboardKeys.Control))
|
||||
if (Root.GetKey(KeyboardKeys.Shift) && transformGizmo.Selection.Contains(uiControlNode))
|
||||
{
|
||||
// Move whole selection
|
||||
}
|
||||
else if (Root.GetKey(KeyboardKeys.Control))
|
||||
{
|
||||
// Add/remove from selection
|
||||
selection.AddRange(transformGizmo.Selection);
|
||||
@@ -261,13 +265,14 @@ namespace FlaxEditor
|
||||
selection.Remove(uiControlNode);
|
||||
else
|
||||
selection.Add(uiControlNode);
|
||||
owner.Select(selection);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select
|
||||
selection.Add(uiControlNode);
|
||||
owner.Select(selection);
|
||||
}
|
||||
owner.Select(selection);
|
||||
|
||||
// Initialize control movement
|
||||
_mouseMovesControl = true;
|
||||
@@ -499,6 +504,15 @@ namespace FlaxEditor
|
||||
bool drawAnySelectedControl = false;
|
||||
var transformGizmo = TransformGizmo;
|
||||
var mousePos = PointFromWindow(RootWindow.MousePosition);
|
||||
if (EnableSelecting && !_mouseMovesControl && !_mouseMovesWidget && IsMouseOver)
|
||||
{
|
||||
// Highlight control under mouse for easier selecting (except if already selected)
|
||||
if (RayCastControl(ref mousePos, out var hitControl) &&
|
||||
(transformGizmo == null || !transformGizmo.Selection.Any(x => x.EditableObject is UIControl controlActor && controlActor.Control == hitControl)))
|
||||
{
|
||||
DrawControl(null, hitControl, false, ref mousePos, ref drawAnySelectedControl);
|
||||
}
|
||||
}
|
||||
if (transformGizmo != null)
|
||||
{
|
||||
// Selected UI controls outline
|
||||
@@ -511,15 +525,6 @@ namespace FlaxEditor
|
||||
}
|
||||
}
|
||||
}
|
||||
if (EnableSelecting && !_mouseMovesControl && !_mouseMovesWidget && IsMouseOver)
|
||||
{
|
||||
// Highlight control under mouse for easier selecting (except if already selected)
|
||||
if (RayCastControl(ref mousePos, out var hitControl) &&
|
||||
(transformGizmo == null || !transformGizmo.Selection.Any(x => x.EditableObject is UIControl controlActor && controlActor.Control == hitControl)))
|
||||
{
|
||||
DrawControl(null, hitControl, false, ref mousePos, ref drawAnySelectedControl);
|
||||
}
|
||||
}
|
||||
if (drawAnySelectedControl)
|
||||
Render2D.PopTransform();
|
||||
|
||||
@@ -617,40 +622,36 @@ namespace FlaxEditor
|
||||
// Draw sizing widgets
|
||||
if (_widgets == null)
|
||||
_widgets = new List<Widget>();
|
||||
var widgetSize = 8.0f;
|
||||
var widgetSize = 10.0f;
|
||||
var viewScale = ViewScale;
|
||||
if (viewScale < 0.7f)
|
||||
widgetSize *= viewScale;
|
||||
var controlSize = control.Size.Absolute.MinValue / 50.0f;
|
||||
if (controlSize < 1.0f)
|
||||
widgetSize *= Mathf.Clamp(controlSize + 0.1f, 0.1f, 1.0f);
|
||||
var cornerSize = new Float2(widgetSize);
|
||||
DrawControlWidget(uiControl, ref ul, ref mousePos, ref cornerSize, new Float2(-1, -1), CursorType.SizeNWSE);
|
||||
DrawControlWidget(uiControl, ref ur, ref mousePos, ref cornerSize, new Float2(1, -1), CursorType.SizeNESW);
|
||||
DrawControlWidget(uiControl, ref bl, ref mousePos, ref cornerSize, new Float2(-1, 1), CursorType.SizeNESW);
|
||||
DrawControlWidget(uiControl, ref br, ref mousePos, ref cornerSize, new Float2(1, 1), CursorType.SizeNWSE);
|
||||
var edgeSizeV = new Float2(widgetSize * 2, widgetSize);
|
||||
var edgeSizeH = new Float2(edgeSizeV.Y, edgeSizeV.X);
|
||||
var widgetHandleSize = new Float2(widgetSize);
|
||||
DrawControlWidget(uiControl, ref ul, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, -1), CursorType.SizeNWSE);
|
||||
DrawControlWidget(uiControl, ref ur, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, -1), CursorType.SizeNESW);
|
||||
DrawControlWidget(uiControl, ref bl, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, 1), CursorType.SizeNESW);
|
||||
DrawControlWidget(uiControl, ref br, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, 1), CursorType.SizeNWSE);
|
||||
Float2.Lerp(ref ul, ref bl, 0.5f, out var el);
|
||||
Float2.Lerp(ref ur, ref br, 0.5f, out var er);
|
||||
Float2.Lerp(ref ul, ref ur, 0.5f, out var eu);
|
||||
Float2.Lerp(ref bl, ref br, 0.5f, out var eb);
|
||||
DrawControlWidget(uiControl, ref el, ref mousePos, ref edgeSizeH, new Float2(-1, 0), CursorType.SizeWE);
|
||||
DrawControlWidget(uiControl, ref er, ref mousePos, ref edgeSizeH, new Float2(1, 0), CursorType.SizeWE);
|
||||
DrawControlWidget(uiControl, ref eu, ref mousePos, ref edgeSizeV, new Float2(0, -1), CursorType.SizeNS);
|
||||
DrawControlWidget(uiControl, ref eb, ref mousePos, ref edgeSizeV, new Float2(0, 1), CursorType.SizeNS);
|
||||
DrawControlWidget(uiControl, ref el, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, 0), CursorType.SizeWE);
|
||||
DrawControlWidget(uiControl, ref er, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, 0), CursorType.SizeWE);
|
||||
DrawControlWidget(uiControl, ref eu, ref mousePos, ref widgetHandleSize, viewScale, new Float2(0, -1), CursorType.SizeNS);
|
||||
DrawControlWidget(uiControl, ref eb, ref mousePos, ref widgetHandleSize, viewScale, new Float2(0, 1), CursorType.SizeNS);
|
||||
|
||||
// TODO: draw anchors
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawControlWidget(UIControl uiControl, ref Float2 pos, ref Float2 mousePos, ref Float2 size, Float2 resizeAxis, CursorType cursor)
|
||||
private void DrawControlWidget(UIControl uiControl, ref Float2 pos, ref Float2 mousePos, ref Float2 size, float scale, Float2 resizeAxis, CursorType cursor)
|
||||
{
|
||||
var style = Style.Current;
|
||||
var rect = new Rectangle(pos - size * 0.5f, size);
|
||||
var rect = new Rectangle((pos + resizeAxis * 10 * scale) - size * 0.5f, size);
|
||||
if (rect.Contains(ref mousePos))
|
||||
{
|
||||
Render2D.FillRectangle(rect, style.Foreground);
|
||||
Render2D.DrawRectangle(rect, style.SelectionBorder);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -433,6 +433,9 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa
|
||||
case InputDevice::EventType::MouseMove:
|
||||
window->OnMouseMove(window->ScreenToClient(e.MouseData.Position));
|
||||
break;
|
||||
case InputDevice::EventType::MouseMoveRelative:
|
||||
window->OnMouseMoveRelative(e.MouseMovementData.PositionRelative);
|
||||
break;
|
||||
case InputDevice::EventType::MouseLeave:
|
||||
window->OnMouseLeave();
|
||||
break;
|
||||
|
||||
@@ -223,6 +223,19 @@ void ManagedEditor::Init()
|
||||
{
|
||||
LOG(Info, "Loading managed assemblies (due to disabled compilation on startup)");
|
||||
Scripting::Load();
|
||||
|
||||
const auto endInitMethod = mclass->GetMethod("EndInit");
|
||||
if (endInitMethod == nullptr)
|
||||
{
|
||||
LOG(Fatal, "Invalid Editor assembly! Missing EndInit method.");
|
||||
}
|
||||
endInitMethod->Invoke(instance, nullptr, &exception);
|
||||
if (exception)
|
||||
{
|
||||
MException ex(exception);
|
||||
ex.Log(LogType::Warning, TEXT("ManagedEditor::EndInit"));
|
||||
LOG_STR(Fatal, TEXT("Failed to initialize editor during EndInit! ") + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
// Call building if need to (based on CL)
|
||||
|
||||
@@ -27,6 +27,7 @@ API_CLASS(Namespace="FlaxEditor", Name="Editor", NoSpawn, NoConstructor) class M
|
||||
byte AutoReloadScriptsOnMainWindowFocus = 1;
|
||||
byte ForceScriptCompilationOnStartup = 1;
|
||||
byte UseAssetImportPathRelative = 1;
|
||||
byte EnableParticlesPreview = 1;
|
||||
byte AutoRebuildCSG = 1;
|
||||
float AutoRebuildCSGTimeoutMs = 50;
|
||||
byte AutoRebuildNavMesh = 1;
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace FlaxEditor.Modules
|
||||
new SearchResult { Name = item.ShortName, Type = assetItem.TypeName, Item = item }
|
||||
};
|
||||
}
|
||||
var actor = FlaxEngine.Object.Find<Actor>(ref id);
|
||||
var actor = FlaxEngine.Object.Find<Actor>(ref id, true);
|
||||
if (actor != null)
|
||||
{
|
||||
return new List<SearchResult>
|
||||
@@ -236,6 +236,16 @@ namespace FlaxEditor.Modules
|
||||
new SearchResult { Name = actor.Name, Type = actor.TypeName, Item = actor }
|
||||
};
|
||||
}
|
||||
var script = FlaxEngine.Object.Find<Script>(ref id, true);
|
||||
if (script != null && script.Actor != null)
|
||||
{
|
||||
string actorPathStart = $"{script.Actor.Name}/";
|
||||
|
||||
return new List<SearchResult>
|
||||
{
|
||||
new SearchResult { Name = $"{actorPathStart}{script.TypeName}", Type = script.TypeName, Item = script }
|
||||
};
|
||||
}
|
||||
}
|
||||
Profiler.BeginEvent("ContentFinding.Search");
|
||||
|
||||
@@ -332,9 +342,10 @@ namespace FlaxEditor.Modules
|
||||
{
|
||||
foreach (var contentItem in items)
|
||||
{
|
||||
var name = contentItem.ShortName;
|
||||
if (contentItem.IsAsset)
|
||||
{
|
||||
if (nameRegex.Match(contentItem.ShortName).Success)
|
||||
if (nameRegex.Match(name).Success)
|
||||
{
|
||||
var asset = contentItem as AssetItem;
|
||||
if (asset == null || !typeRegex.Match(asset.TypeName).Success)
|
||||
@@ -348,7 +359,7 @@ namespace FlaxEditor.Modules
|
||||
var splits = asset.TypeName.Split('.');
|
||||
finalName = splits[splits.Length - 1];
|
||||
}
|
||||
matches.Add(new SearchResult { Name = asset.ShortName, Type = finalName, Item = asset });
|
||||
matches.Add(new SearchResult { Name = name, Type = finalName, Item = asset });
|
||||
}
|
||||
}
|
||||
else if (contentItem.IsFolder)
|
||||
@@ -360,11 +371,12 @@ namespace FlaxEditor.Modules
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nameRegex.Match(contentItem.ShortName).Success && typeRegex.Match(contentItem.GetType().Name).Success)
|
||||
if (nameRegex.Match(name).Success && typeRegex.Match(contentItem.GetType().Name).Success)
|
||||
{
|
||||
string finalName = contentItem.GetType().Name.Replace("Item", "");
|
||||
|
||||
matches.Add(new SearchResult { Name = contentItem.ShortName, Type = finalName, Item = contentItem });
|
||||
if (contentItem is ScriptItem)
|
||||
name = contentItem.FileName; // Show extension for scripts (esp. for .h and .cpp files of the same name)
|
||||
matches.Add(new SearchResult { Name = name, Type = finalName, Item = contentItem });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -388,6 +400,13 @@ namespace FlaxEditor.Modules
|
||||
Editor.Instance.SceneEditing.Select(actor);
|
||||
Editor.Instance.Windows.EditWin.Viewport.FocusSelection();
|
||||
break;
|
||||
case Script script:
|
||||
if (script.Actor != null)
|
||||
{
|
||||
Editor.Instance.SceneEditing.Select(script.Actor);
|
||||
Editor.Instance.Windows.EditWin.Viewport.FocusSelection();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -202,6 +202,7 @@ namespace FlaxEditor.Modules
|
||||
|
||||
var prefabId = ((ActorNode)selection[0]).Actor.PrefabID;
|
||||
var prefab = FlaxEngine.Content.LoadAsync<Prefab>(prefabId);
|
||||
Editor.Windows.ContentWin.ClearItemsSearch();
|
||||
Editor.Windows.ContentWin.Select(prefab);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.Modules
|
||||
@@ -119,6 +121,30 @@ namespace FlaxEditor.Modules
|
||||
return _customData.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the custom data by the key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="value">When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of the <paramref name="value" /> parameter. This parameter is passed uninitialized.</param>
|
||||
/// <returns>The custom data.</returns>
|
||||
public bool TryGetCustomData(string key, out bool value)
|
||||
{
|
||||
value = false;
|
||||
return _customData.TryGetValue(key, out var valueStr) && bool.TryParse(valueStr, out value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the custom data by the key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="value">When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of the <paramref name="value" /> parameter. This parameter is passed uninitialized.</param>
|
||||
/// <returns>The custom data.</returns>
|
||||
public bool TryGetCustomData(string key, out float value)
|
||||
{
|
||||
value = 0.0f;
|
||||
return _customData.TryGetValue(key, out var valueStr) && float.TryParse(valueStr, out value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the custom data.
|
||||
/// </summary>
|
||||
@@ -130,6 +156,28 @@ namespace FlaxEditor.Modules
|
||||
_isDirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the custom data.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetCustomData(string key, bool value)
|
||||
{
|
||||
SetCustomData(key, value.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the custom data.
|
||||
/// </summary>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SetCustomData(string key, float value)
|
||||
{
|
||||
SetCustomData(key, value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the custom data.
|
||||
/// </summary>
|
||||
|
||||
@@ -182,6 +182,9 @@ namespace FlaxEditor.Modules
|
||||
var cam = scene.AddChild<Camera>();
|
||||
cam.Name = "Camera";
|
||||
cam.Position = new Vector3(0, 150, -300);
|
||||
//
|
||||
var audioListener = cam.AddChild<AudioListener>();
|
||||
audioListener.Name = "Audio Listener";
|
||||
|
||||
// Serialize
|
||||
var bytes = Level.SaveSceneToBytes(scene);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user