Compare commits
354 Commits
woa_suppor
...
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 | ||
|
|
d8ca8f5985 | ||
|
|
ac36297e27 | ||
|
|
7fef21218e | ||
| 7aa4ae1782 | |||
| dd7739f95e | |||
|
|
203f5d06d1 | ||
|
|
c6515da8c9 | ||
|
|
5d61e45ecd | ||
|
|
2bec653b81 |
@@ -1,4 +1,4 @@
|
|||||||
# Redirect to our own Git LFS server
|
# Redirect to our own Git LFS server
|
||||||
[lfs]
|
[lfs]
|
||||||
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||||
locksverify = false
|
locksverify = false
|
||||||
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"
|
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||||
@2// Forward Shading: Constants
|
@2// Forward Shading: Constants
|
||||||
LightData DirectionalLight;
|
LightData DirectionalLight;
|
||||||
|
LightShadowData DirectionalLightShadow;
|
||||||
LightData SkyLight;
|
LightData SkyLight;
|
||||||
ProbeData EnvironmentProbe;
|
ProbeData EnvironmentProbe;
|
||||||
ExponentialHeightFogData ExponentialHeightFog;
|
ExponentialHeightFogData ExponentialHeightFog;
|
||||||
@@ -25,9 +26,9 @@ LightData LocalLights[MAX_LOCAL_LIGHTS];
|
|||||||
@3// Forward Shading: Resources
|
@3// Forward Shading: Resources
|
||||||
TextureCube EnvProbe : register(t__SRV__);
|
TextureCube EnvProbe : register(t__SRV__);
|
||||||
TextureCube SkyLightTexture : register(t__SRV__);
|
TextureCube SkyLightTexture : register(t__SRV__);
|
||||||
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
Texture2DArray DirectionalLightShadowMap : register(t__SRV__);
|
||||||
Texture2D<float> ShadowMap : register(t__SRV__);
|
|
||||||
@4// Forward Shading: Utilities
|
@4// Forward Shading: Utilities
|
||||||
|
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||||
@5// Forward Shading: Shaders
|
@5// Forward Shading: Shaders
|
||||||
|
|
||||||
// Pixel Shader function for Forward Pass
|
// Pixel Shader function for Forward Pass
|
||||||
@@ -79,8 +80,11 @@ void PS_Forward(
|
|||||||
|
|
||||||
// Calculate lighting from a single directional light
|
// Calculate lighting from a single directional light
|
||||||
float4 shadowMask = 1.0f;
|
float4 shadowMask = 1.0f;
|
||||||
ShadowSample shadow = SampleDirectionalLightShadow(DirectionalLight, ShadowsBuffer, ShadowMap, gBuffer);
|
if (DirectionalLight.CastShadows > 0)
|
||||||
shadowMask = GetShadowMask(shadow);
|
{
|
||||||
|
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||||
|
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||||
|
}
|
||||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||||
|
|
||||||
// Calculate lighting from sky light
|
// Calculate lighting from sky light
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ struct RibbonInput
|
|||||||
|
|
||||||
// Primary constant buffer (with additional material parameters)
|
// Primary constant buffer (with additional material parameters)
|
||||||
META_CB_BEGIN(0, Data)
|
META_CB_BEGIN(0, Data)
|
||||||
float4x3 WorldMatrix;
|
float4x4 WorldMatrix;
|
||||||
uint SortedIndicesOffset;
|
uint SortedIndicesOffset;
|
||||||
float PerInstanceRandom;
|
float PerInstanceRandom;
|
||||||
int ParticleStride;
|
int ParticleStride;
|
||||||
@@ -45,7 +45,7 @@ int RibbonWidthOffset;
|
|||||||
int RibbonTwistOffset;
|
int RibbonTwistOffset;
|
||||||
int RibbonFacingVectorOffset;
|
int RibbonFacingVectorOffset;
|
||||||
uint RibbonSegmentCount;
|
uint RibbonSegmentCount;
|
||||||
float4x3 WorldMatrixInverseTransposed;
|
float4x4 WorldMatrixInverseTransposed;
|
||||||
@1META_CB_END
|
@1META_CB_END
|
||||||
|
|
||||||
// Particles attributes buffer
|
// Particles attributes buffer
|
||||||
@@ -138,7 +138,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
|||||||
#if USE_INSTANCING
|
#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))
|
#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
|
#else
|
||||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
#define GetInstanceTransform(input) WorldMatrix;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
// 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)
|
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)
|
float3 TransformParticleVector(float3 input)
|
||||||
{
|
{
|
||||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@8
|
@8
|
||||||
@@ -333,7 +333,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
|||||||
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
|
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
|
||||||
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
|
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
|
||||||
|
|
||||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
float4x4 world = WorldMatrix;
|
||||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||||
float3x3 viewRot = transpose((float3x3)ViewMatrix);
|
float3x3 viewRot = transpose((float3x3)ViewMatrix);
|
||||||
float3 position = mul(float4(particlePosition, 1), world).xyz;
|
float3 position = mul(float4(particlePosition, 1), world).xyz;
|
||||||
@@ -463,12 +463,11 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read particle data
|
// Read particle data
|
||||||
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
|
||||||
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
|
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
|
||||||
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
|
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
|
||||||
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
|
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
|
||||||
int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1;
|
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
|
// Compute final vertex position in the world
|
||||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||||
@@ -507,7 +506,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
|||||||
world = mul(world, scaleMatrix);
|
world = mul(world, scaleMatrix);
|
||||||
}
|
}
|
||||||
world = transpose(world);
|
world = transpose(world);
|
||||||
world = mul(world, worldMatrix);
|
world = mul(world, WorldMatrix);
|
||||||
|
|
||||||
// Calculate the vertex position in world space
|
// Calculate the vertex position in world space
|
||||||
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
|
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
|
#if USE_VERTEX_COLOR
|
||||||
output.VertexColor = input.Color;
|
output.VertexColor = input.Color;
|
||||||
#endif
|
#endif
|
||||||
output.InstanceOrigin = worldMatrix[3].xyz;
|
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||||
output.InstanceParams = PerInstanceRandom;
|
output.InstanceParams = PerInstanceRandom;
|
||||||
|
|
||||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||||
half3x3 tangentToLocal = CalcTangentToLocal(input);
|
half3x3 tangentToLocal = CalcTangentToLocal(input);
|
||||||
half3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||||
output.TBN = tangentToWorld;
|
output.TBN = tangentToWorld;
|
||||||
|
|
||||||
// Get material input params if need to evaluate any material property
|
// 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
|
#if USE_VERTEX_COLOR
|
||||||
output.VertexColor = 1;
|
output.VertexColor = 1;
|
||||||
#endif
|
#endif
|
||||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||||
output.InstanceOrigin = world[3].xyz;
|
|
||||||
output.InstanceParams = PerInstanceRandom;
|
output.InstanceParams = PerInstanceRandom;
|
||||||
|
|
||||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||||
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
|
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
|
||||||
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
|
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||||
output.TBN = tangentToWorld;
|
output.TBN = tangentToWorld;
|
||||||
|
|
||||||
// Get material input params if need to evaluate any material property
|
// Get material input params if need to evaluate any material property
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
@7
|
@7
|
||||||
// Primary constant buffer (with additional material parameters)
|
// Primary constant buffer (with additional material parameters)
|
||||||
META_CB_BEGIN(0, Data)
|
META_CB_BEGIN(0, Data)
|
||||||
float4x3 WorldMatrix;
|
float4x4 WorldMatrix;
|
||||||
float4x3 PrevWorldMatrix;
|
float4x4 PrevWorldMatrix;
|
||||||
float2 Dummy0;
|
float2 Dummy0;
|
||||||
float LODDitherFactor;
|
float LODDitherFactor;
|
||||||
float PerInstanceRandom;
|
float PerInstanceRandom;
|
||||||
@@ -171,7 +171,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
|||||||
#if USE_INSTANCING
|
#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;
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
// 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
|
// Compute world space vertex position
|
||||||
CalculateInstanceTransform(input);
|
CalculateInstanceTransform(input);
|
||||||
output.Geometry.WorldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
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
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
@@ -402,7 +402,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
|
|||||||
#if USE_INSTANCING
|
#if USE_INSTANCING
|
||||||
float4x4 world = GetInstanceTransform(input);
|
float4x4 world = GetInstanceTransform(input);
|
||||||
#else
|
#else
|
||||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
float4x4 world = WorldMatrix;
|
||||||
#endif
|
#endif
|
||||||
float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||||
float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix);
|
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;
|
output.Geometry.WorldPosition = mul(float4(position, 1), world).xyz;
|
||||||
#if PER_BONE_MOTION_BLUR
|
#if PER_BONE_MOTION_BLUR
|
||||||
float3 prevPosition = SkinPrevPosition(input);
|
float3 prevPosition = SkinPrevPosition(input);
|
||||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), PrevWorldMatrix).xyz;
|
||||||
#else
|
#else
|
||||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
output.Geometry.PrevWorldPosition = mul(float4(position, 1), PrevWorldMatrix).xyz;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Compute clip space position
|
// Compute clip space position
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
@7
|
@7
|
||||||
// Primary constant buffer (with additional material parameters)
|
// Primary constant buffer (with additional material parameters)
|
||||||
META_CB_BEGIN(0, Data)
|
META_CB_BEGIN(0, Data)
|
||||||
float4x3 WorldMatrix;
|
float4x4 WorldMatrix;
|
||||||
float3 WorldInvScale;
|
float3 WorldInvScale;
|
||||||
float WorldDeterminantSign;
|
float WorldDeterminantSign;
|
||||||
float PerInstanceRandom;
|
float PerInstanceRandom;
|
||||||
@@ -194,7 +194,7 @@ float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
|
|||||||
// Transforms a vector from local space to world space
|
// Transforms a vector from local space to world space
|
||||||
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||||
{
|
{
|
||||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||||
return mul(localVector, localToWorld);
|
return mul(localVector, localToWorld);
|
||||||
}
|
}
|
||||||
@@ -202,7 +202,7 @@ float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
|||||||
// Transforms a vector from local space to world space
|
// Transforms a vector from local space to world space
|
||||||
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||||
{
|
{
|
||||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||||
return mul(localToWorld, worldVector);
|
return mul(localToWorld, worldVector);
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
|||||||
// Gets the current object position
|
// Gets the current object position
|
||||||
float3 GetObjectPosition(MaterialInput input)
|
float3 GetObjectPosition(MaterialInput input)
|
||||||
{
|
{
|
||||||
return ToMatrix4x4(WorldMatrix)[3].xyz;
|
return WorldMatrix[3].xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the current object size
|
// Gets the current object size
|
||||||
@@ -365,8 +365,7 @@ VertexOutput VS(TerrainVertexInput input)
|
|||||||
float3 position = float3(positionXZ.x, height, positionXZ.y);
|
float3 position = float3(positionXZ.x, height, positionXZ.y);
|
||||||
|
|
||||||
// Compute world space vertex position
|
// 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
|
// Compute clip space position
|
||||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||||
@@ -390,7 +389,7 @@ VertexOutput VS(TerrainVertexInput input)
|
|||||||
|
|
||||||
// Compute world space normal vector
|
// Compute world space normal vector
|
||||||
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
|
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
|
||||||
float3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
float3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||||
output.Geometry.WorldNormal = tangentToWorld[2];
|
output.Geometry.WorldNormal = tangentToWorld[2];
|
||||||
|
|
||||||
// Get material input params if need to evaluate any material property
|
// Get material input params if need to evaluate any material property
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
// Primary constant buffer (with additional material parameters)
|
// Primary constant buffer (with additional material parameters)
|
||||||
META_CB_BEGIN(0, Data)
|
META_CB_BEGIN(0, Data)
|
||||||
float4x4 InverseViewProjectionMatrix;
|
float4x4 InverseViewProjectionMatrix;
|
||||||
float4x3 WorldMatrix;
|
float4x4 WorldMatrix;
|
||||||
float4x3 WorldMatrixInverseTransposed;
|
float4x4 WorldMatrixInverseTransposed;
|
||||||
float3 GridSize;
|
float3 GridSize;
|
||||||
float PerInstanceRandom;
|
float PerInstanceRandom;
|
||||||
float Dummy0;
|
float Dummy0;
|
||||||
@@ -49,7 +49,7 @@ struct MaterialInput
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
#define GetInstanceTransform(input) WorldMatrix;
|
||||||
|
|
||||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||||
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
|
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
|
||||||
@@ -170,12 +170,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
|||||||
|
|
||||||
float3 TransformParticlePosition(float3 input)
|
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)
|
float3 TransformParticleVector(float3 input)
|
||||||
{
|
{
|
||||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@8
|
@8
|
||||||
@@ -219,7 +219,7 @@ void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out fl
|
|||||||
materialInput.ParticleIndex = ParticleIndex;
|
materialInput.ParticleIndex = ParticleIndex;
|
||||||
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
||||||
materialInput.TwoSidedSign = 1.0f;
|
materialInput.TwoSidedSign = 1.0f;
|
||||||
materialInput.InstanceOrigin = ToMatrix4x4(WorldMatrix)[3].xyz;
|
materialInput.InstanceOrigin = WorldMatrix[3].xyz;
|
||||||
materialInput.InstanceParams = PerInstanceRandom;
|
materialInput.InstanceParams = PerInstanceRandom;
|
||||||
materialInput.SvPosition = clipPos;
|
materialInput.SvPosition = clipPos;
|
||||||
Material material = GetMaterialPS(materialInput);
|
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",
|
"Name": "Flax",
|
||||||
"Version": {
|
"Version": {
|
||||||
"Major": 1,
|
"Major": 1,
|
||||||
"Minor": 9,
|
"Minor": 8,
|
||||||
"Revision": 0,
|
"Revision": 2,
|
||||||
"Build": 6601
|
"Build": 6512
|
||||||
},
|
},
|
||||||
"Company": "Flax",
|
"Company": "Flax",
|
||||||
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
|
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
"Configuration": {
|
"Configuration": {
|
||||||
"UseCSharp": true,
|
"UseCSharp": true,
|
||||||
"UseLargeWorlds": false,
|
"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/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION_005FMEMBER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION_005FMEMBER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ARGB/@EntryIndexedValue">ARGB</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LO/@EntryIndexedValue">LO</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/=RPC/@EntryIndexedValue">RPC</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String>
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ call "Development\Scripts\Windows\CallBuildTool.bat" -genproject %*
|
|||||||
if errorlevel 1 goto BuildToolFailed
|
if errorlevel 1 goto BuildToolFailed
|
||||||
|
|
||||||
:: Build bindings for all editor configurations
|
:: Build bindings for all editor configurations
|
||||||
::echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
::Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
||||||
|
|
||||||
popd
|
popd
|
||||||
echo Done!
|
echo Done!
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
@@ -96,8 +94,30 @@ public class AssetPickerValidator : IContentItemOwner
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string SelectedPath
|
public string SelectedPath
|
||||||
{
|
{
|
||||||
get => Utilities.Utils.ToPathProject(_selectedItem?.Path ?? _selected?.Path);
|
get
|
||||||
set => SelectedItem = string.IsNullOrEmpty(value) ? null : Editor.Instance.ContentDatabase.Find(Utilities.Utils.ToPathAbsolute(value));
|
{
|
||||||
|
string path = _selectedItem?.Path ?? _selected?.Path;
|
||||||
|
if (path != null)
|
||||||
|
{
|
||||||
|
// Convert into path relative to the project (cross-platform)
|
||||||
|
var projectFolder = Globals.ProjectFolder;
|
||||||
|
if (path.StartsWith(projectFolder))
|
||||||
|
path = path.Substring(projectFolder.Length + 1);
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
SelectedItem = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var path = StringUtils.IsRelative(value) ? Path.Combine(Globals.ProjectFolder, value) : value;
|
||||||
|
SelectedItem = Editor.Instance.ContentDatabase.Find(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -222,7 +242,7 @@ public class AssetPickerValidator : IContentItemOwner
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="AssetPickerValidator"/> class.
|
/// Initializes a new instance of the <see cref="AssetPickerValidator"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="assetType">The asset types that this picker accepts.</param>
|
/// <param name="assetType">The assets types that this picker accepts.</param>
|
||||||
public AssetPickerValidator(ScriptType assetType)
|
public AssetPickerValidator(ScriptType assetType)
|
||||||
{
|
{
|
||||||
_type = assetType;
|
_type = assetType;
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ namespace FlaxEditor.Content.GUI
|
|||||||
private bool _isRubberBandSpanning;
|
private bool _isRubberBandSpanning;
|
||||||
private Float2 _mousePressLocation;
|
private Float2 _mousePressLocation;
|
||||||
private Rectangle _rubberBandRectangle;
|
private Rectangle _rubberBandRectangle;
|
||||||
|
private bool _isCutting;
|
||||||
|
private List<ContentItem> _cutItems = new List<ContentItem>();
|
||||||
|
|
||||||
private bool _validDragOver;
|
private bool _validDragOver;
|
||||||
private DragActors _dragActors;
|
private DragActors _dragActors;
|
||||||
@@ -83,9 +85,9 @@ namespace FlaxEditor.Content.GUI
|
|||||||
public event Action<List<ContentItem>> OnDelete;
|
public event Action<List<ContentItem>> OnDelete;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when user wants to paste the files/folders.
|
/// Called when user wants to paste the files/folders. Bool is for cutting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<string[]> OnPaste;
|
public event Action<string[], bool> OnPaste;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when user wants to duplicate the item(s).
|
/// 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.Copy, Copy),
|
||||||
new InputActionsContainer.Binding(options => options.Paste, Paste),
|
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),
|
new InputActionsContainer.Binding(options => options.Duplicate, Duplicate),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -462,6 +470,7 @@ namespace FlaxEditor.Content.GUI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Duplicate()
|
public void Duplicate()
|
||||||
{
|
{
|
||||||
|
UpdateContentItemCut(false);
|
||||||
OnDuplicate?.Invoke(_selection);
|
OnDuplicate?.Invoke(_selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,6 +484,7 @@ namespace FlaxEditor.Content.GUI
|
|||||||
|
|
||||||
var files = _selection.ConvertAll(x => x.Path).ToArray();
|
var files = _selection.ConvertAll(x => x.Path).ToArray();
|
||||||
Clipboard.Files = files;
|
Clipboard.Files = files;
|
||||||
|
UpdateContentItemCut(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -496,7 +506,36 @@ namespace FlaxEditor.Content.GUI
|
|||||||
if (files == null || files.Length == 0)
|
if (files == null || files.Length == 0)
|
||||||
return;
|
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>
|
/// <summary>
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ namespace FlaxEngine.Tools
|
|||||||
FieldInfo[] fields = typeof(CustomMaxSizes).GetFields();
|
FieldInfo[] fields = typeof(CustomMaxSizes).GetFields();
|
||||||
for (int i = 0; i < fields.Length; i++)
|
for (int i = 0; i < fields.Length; i++)
|
||||||
{
|
{
|
||||||
var field = fields[i];
|
var @field = fields[i];
|
||||||
if (field.Name.Equals("value__"))
|
if (@field.Name.Equals("value__"))
|
||||||
continue;
|
continue;
|
||||||
if (value == (int)field.GetRawConstantValue())
|
if (value == (int)@field.GetRawConstantValue())
|
||||||
return (CustomMaxSizes)value;
|
return (CustomMaxSizes)value;
|
||||||
}
|
}
|
||||||
return CustomMaxSizes._8192;
|
return CustomMaxSizes._8192;
|
||||||
|
|||||||
@@ -182,6 +182,11 @@ namespace FlaxEditor.Content
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const int DefaultHeight = (DefaultThumbnailSize + 2 * DefaultMarginSize + DefaultTextHeight);
|
public const int DefaultHeight = (DefaultThumbnailSize + 2 * DefaultMarginSize + DefaultTextHeight);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the item is being but.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsBeingCut;
|
||||||
|
|
||||||
private ContentFolder _parentFolder;
|
private ContentFolder _parentFolder;
|
||||||
|
|
||||||
private bool _isMouseDown;
|
private bool _isMouseDown;
|
||||||
@@ -747,6 +752,12 @@ namespace FlaxEditor.Content
|
|||||||
Render2D.PushClip(ref textRect);
|
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.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, 0.95f);
|
||||||
Render2D.PopClip();
|
Render2D.PopClip();
|
||||||
|
|
||||||
|
if (IsBeingCut)
|
||||||
|
{
|
||||||
|
var color = style.LightBackground.AlphaMultiplied(0.5f);
|
||||||
|
Render2D.FillRectangle(clientRect, color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
using FlaxEngine;
|
|
||||||
|
|
||||||
namespace FlaxEditor.Content
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Content item that contains video media file.
|
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="FlaxEditor.Content.JsonAssetItem" />
|
|
||||||
public sealed class VideoItem : FileItem
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="VideoItem"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The file path.</param>
|
|
||||||
public VideoItem(string path)
|
|
||||||
: base(path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override string TypeDescription => "Video";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.Document128;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -100,12 +100,16 @@ namespace FlaxEditor.Content
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object GetValue(object obj)
|
public object GetValue(object obj)
|
||||||
{
|
{
|
||||||
|
if (!_type.Asset)
|
||||||
|
throw new TargetException("Missing Visual Script asset.");
|
||||||
return _type.Asset.GetScriptInstanceParameterValue(_parameter.Name, (Object)obj);
|
return _type.Asset.GetScriptInstanceParameterValue(_parameter.Name, (Object)obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SetValue(object obj, object value)
|
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);
|
_type.Asset.SetScriptInstanceParameterValue(_parameter.Name, (Object)obj, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ namespace FlaxEditor.Content
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether [is virtual proxy].
|
/// Determines whether [is virtual proxy].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns><c>true</c> if [is virtual proxy]; otherwise, <c>false</c>.</returns>
|
/// <returns>
|
||||||
|
/// <c>true</c> if [is virtual proxy]; otherwise, <c>false</c>.
|
||||||
|
/// </returns>
|
||||||
public bool IsVirtualProxy()
|
public bool IsVirtualProxy()
|
||||||
{
|
{
|
||||||
return IsVirtual && CanExport == false;
|
return IsVirtual && CanExport == false;
|
||||||
|
|||||||
@@ -29,12 +29,6 @@ namespace FlaxEditor.Content
|
|||||||
return item is CSharpScriptItem;
|
return item is CSharpScriptItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override ContentItem ConstructItem(string path)
|
|
||||||
{
|
|
||||||
return new CSharpScriptItem(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Create(string outputPath, object arg)
|
public override void Create(string outputPath, object arg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,16 +39,6 @@ namespace FlaxEditor.Content
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs the item for the file.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The file path.</param>
|
|
||||||
/// <returns>Created item or null.</returns>
|
|
||||||
public virtual ContentItem ConstructItem(string path)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this proxy if for assets.
|
/// Gets a value indicating whether this proxy if for assets.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -87,12 +87,6 @@ namespace FlaxEditor.Content
|
|||||||
return item is CppScriptItem;
|
return item is CppScriptItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override ContentItem ConstructItem(string path)
|
|
||||||
{
|
|
||||||
return new CppScriptItem(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void GetTemplatePaths(out string headerTemplate, out string sourceTemplate)
|
protected override void GetTemplatePaths(out string headerTemplate, out string sourceTemplate)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,12 +20,6 @@ namespace FlaxEditor.Content
|
|||||||
return item is FileItem;
|
return item is FileItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override ContentItem ConstructItem(string path)
|
|
||||||
{
|
|
||||||
return new FileItem(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string FileExtension => string.Empty;
|
public override string FileExtension => string.Empty;
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,18 @@ namespace FlaxEditor.Content
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string Name { get; } = Utilities.Utils.GetPropertyNameUI(typeof(T).Name);
|
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 />
|
/// <inheritdoc />
|
||||||
public override bool CanCreate(ContentFolder targetLocation)
|
public override bool CanCreate(ContentFolder targetLocation)
|
||||||
{
|
{
|
||||||
@@ -177,6 +189,12 @@ namespace FlaxEditor.Content
|
|||||||
{
|
{
|
||||||
Editor.SaveJsonAsset(outputPath, new T());
|
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 />
|
/// <inheritdoc />
|
||||||
public override string TypeName { get; } = typeof(T).FullName;
|
public override string TypeName { get; } = typeof(T).FullName;
|
||||||
|
|||||||
@@ -73,16 +73,6 @@ namespace FlaxEditor.Content
|
|||||||
return targetLocation.CanHaveAssets;
|
return targetLocation.CanHaveAssets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool CanReimport(ContentItem item)
|
|
||||||
{
|
|
||||||
if (item is not PrefabItem prefabItem)
|
|
||||||
return base.CanReimport(item);
|
|
||||||
|
|
||||||
var prefab = FlaxEngine.Content.Load<Prefab>(prefabItem.ID);
|
|
||||||
return prefab.GetDefaultInstance().GetScript<ModelPrefab>() != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Create(string outputPath, object arg)
|
public override void Create(string outputPath, object arg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
using FlaxEditor.Windows;
|
|
||||||
using FlaxEditor.Windows.Assets;
|
|
||||||
using FlaxEngine;
|
|
||||||
|
|
||||||
namespace FlaxEditor.Content
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A video media file proxy object.
|
|
||||||
/// </summary>
|
|
||||||
public class VideoProxy : ContentProxy
|
|
||||||
{
|
|
||||||
private readonly string _extension;
|
|
||||||
|
|
||||||
internal VideoProxy(string extension)
|
|
||||||
{
|
|
||||||
_extension = extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override string Name => "Video";
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override string FileExtension => _extension;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override Color AccentColor => Color.FromRGB(0x11f7f1);
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool IsProxyFor(ContentItem item)
|
|
||||||
{
|
|
||||||
return item is VideoItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override ContentItem ConstructItem(string path)
|
|
||||||
{
|
|
||||||
return new VideoItem(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override EditorWindow Open(Editor editor, ContentItem item)
|
|
||||||
{
|
|
||||||
return new VideoWindow(editor, (VideoItem)item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -134,12 +134,6 @@ API_ENUM() enum class BuildPlatform
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_ENUM(Attributes="EditorDisplay(null, \"iOS ARM64\")")
|
API_ENUM(Attributes="EditorDisplay(null, \"iOS ARM64\")")
|
||||||
iOSARM64 = 14,
|
iOSARM64 = 14,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Windows (ARM64)
|
|
||||||
/// </summary>
|
|
||||||
API_ENUM(Attributes = "EditorDisplay(null, \"Windows ARM64\")")
|
|
||||||
WindowsARM64 = 15,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -291,22 +285,24 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The total assets amount in the build.
|
/// The total assets amount in the build.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int32 TotalAssets = 0;
|
int32 TotalAssets;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cooked assets (TotalAssets - CookedAssets is amount of reused cached assets).
|
/// The cooked assets (TotalAssets - CookedAssets is amount of reused cached assets).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int32 CookedAssets = 0;
|
int32 CookedAssets;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The final output content size (in bytes).
|
/// The final output content size in MB.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
uint64 ContentSize = 0;
|
int32 ContentSizeMB;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The asset type stats. Key is the asset typename, value is the stats container.
|
/// The asset type stats. Key is the asset typename, value is the stats container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Dictionary<String, AssetTypeStatistics> AssetStats;
|
Dictionary<String, AssetTypeStatistics> AssetStats;
|
||||||
|
|
||||||
|
Statistics();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -332,11 +328,6 @@ public:
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
HashSet<Guid> Assets;
|
HashSet<Guid> Assets;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The final files collection to include in build (valid only after CollectAssetsStep).
|
|
||||||
/// </summary>
|
|
||||||
HashSet<String> Files;
|
|
||||||
|
|
||||||
struct BinaryModuleInfo
|
struct BinaryModuleInfo
|
||||||
{
|
{
|
||||||
String Name;
|
String Name;
|
||||||
|
|||||||
@@ -148,8 +148,6 @@ const Char* ToString(const BuildPlatform platform)
|
|||||||
return TEXT("Mac ARM64");
|
return TEXT("Mac ARM64");
|
||||||
case BuildPlatform::iOSARM64:
|
case BuildPlatform::iOSARM64:
|
||||||
return TEXT("iOS ARM64");
|
return TEXT("iOS ARM64");
|
||||||
case BuildPlatform::WindowsARM64:
|
|
||||||
return TEXT("Windows ARM64");
|
|
||||||
default:
|
default:
|
||||||
return TEXT("");
|
return TEXT("");
|
||||||
}
|
}
|
||||||
@@ -204,6 +202,13 @@ bool CookingData::AssetTypeStatistics::operator<(const AssetTypeStatistics& othe
|
|||||||
return Count > other.Count;
|
return Count > other.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CookingData::Statistics::Statistics()
|
||||||
|
{
|
||||||
|
TotalAssets = 0;
|
||||||
|
CookedAssets = 0;
|
||||||
|
ContentSizeMB = 0;
|
||||||
|
}
|
||||||
|
|
||||||
CookingData::CookingData(const SpawnParams& params)
|
CookingData::CookingData(const SpawnParams& params)
|
||||||
: ScriptingObject(params)
|
: ScriptingObject(params)
|
||||||
{
|
{
|
||||||
@@ -302,10 +307,6 @@ void CookingData::GetBuildPlatformName(const Char*& platform, const Char*& archi
|
|||||||
platform = TEXT("iOS");
|
platform = TEXT("iOS");
|
||||||
architecture = TEXT("ARM64");
|
architecture = TEXT("ARM64");
|
||||||
break;
|
break;
|
||||||
case BuildPlatform::WindowsARM64:
|
|
||||||
platform = TEXT("Windows");
|
|
||||||
architecture = TEXT("ARM64");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
LOG(Fatal, "Unknown or unsupported build platform.");
|
LOG(Fatal, "Unknown or unsupported build platform.");
|
||||||
}
|
}
|
||||||
@@ -392,9 +393,6 @@ PlatformTools* GameCooker::GetTools(BuildPlatform platform)
|
|||||||
case BuildPlatform::Windows64:
|
case BuildPlatform::Windows64:
|
||||||
result = New<WindowsPlatformTools>(ArchitectureType::x64);
|
result = New<WindowsPlatformTools>(ArchitectureType::x64);
|
||||||
break;
|
break;
|
||||||
case BuildPlatform::WindowsARM64:
|
|
||||||
result = New<WindowsPlatformTools>(ArchitectureType::ARM64);
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
#if PLATFORM_TOOLS_UWP
|
#if PLATFORM_TOOLS_UWP
|
||||||
case BuildPlatform::UWPx86:
|
case BuildPlatform::UWPx86:
|
||||||
@@ -556,12 +554,7 @@ void GameCooker::GetCurrentPlatform(PlatformType& platform, BuildPlatform& build
|
|||||||
switch (PLATFORM_TYPE)
|
switch (PLATFORM_TYPE)
|
||||||
{
|
{
|
||||||
case PlatformType::Windows:
|
case PlatformType::Windows:
|
||||||
if (PLATFORM_ARCH == ArchitectureType::x64)
|
buildPlatform = PLATFORM_64BITS ? BuildPlatform::Windows64 : BuildPlatform::Windows32;
|
||||||
buildPlatform = BuildPlatform::Windows64;
|
|
||||||
else if (PLATFORM_ARCH == ArchitectureType::ARM64)
|
|
||||||
buildPlatform = BuildPlatform::WindowsARM64;
|
|
||||||
else
|
|
||||||
buildPlatform = BuildPlatform::Windows32;
|
|
||||||
break;
|
break;
|
||||||
case PlatformType::XboxOne:
|
case PlatformType::XboxOne:
|
||||||
buildPlatform = BuildPlatform::XboxOne;
|
buildPlatform = BuildPlatform::XboxOne;
|
||||||
|
|||||||
@@ -325,7 +325,9 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
|
|
||||||
const auto buildSettings = BuildSettings::Get();
|
const auto buildSettings = BuildSettings::Get();
|
||||||
if (buildSettings->SkipPackaging)
|
if (buildSettings->SkipPackaging)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
GameCooker::PackageFiles();
|
GameCooker::PackageFiles();
|
||||||
|
|
||||||
// Validate environment variables
|
// Validate environment variables
|
||||||
|
|||||||
@@ -10,26 +10,47 @@
|
|||||||
#include "Engine/Content/Assets/Shader.h"
|
#include "Engine/Content/Assets/Shader.h"
|
||||||
#include "Engine/Content/Cache/AssetsCache.h"
|
#include "Engine/Content/Cache/AssetsCache.h"
|
||||||
|
|
||||||
|
bool CollectAssetsStep::Process(CookingData& data, Asset* asset)
|
||||||
|
{
|
||||||
|
// Skip virtual/temporary assets
|
||||||
|
if (asset->IsVirtual())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Keep reference to the asset
|
||||||
|
AssetReference<Asset> ref(asset);
|
||||||
|
|
||||||
|
// Asset should have loaded data
|
||||||
|
if (asset->WaitForLoaded())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Gather asset references
|
||||||
|
_references.Clear();
|
||||||
|
asset->Locker.Lock();
|
||||||
|
asset->GetReferences(_references);
|
||||||
|
asset->Locker.Unlock();
|
||||||
|
_assetsQueue.Add(_references);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CollectAssetsStep::Perform(CookingData& data)
|
bool CollectAssetsStep::Perform(CookingData& data)
|
||||||
{
|
{
|
||||||
LOG(Info, "Searching for assets to include in a build. Using {0} root assets.", data.RootAssets.Count());
|
LOG(Info, "Searching for assets to include in a build. Using {0} root assets.", data.RootAssets.Count());
|
||||||
data.StepProgress(TEXT("Collecting assets"), 0);
|
data.StepProgress(TEXT("Collecting assets"), 0);
|
||||||
|
|
||||||
// Initialize assets queue
|
// Initialize assets queue
|
||||||
Array<Guid> assetsQueue;
|
_assetsQueue.Clear();
|
||||||
assetsQueue.Clear();
|
_assetsQueue.EnsureCapacity(1024);
|
||||||
assetsQueue.EnsureCapacity(1024);
|
|
||||||
for (auto i = data.RootAssets.Begin(); i.IsNotEnd(); ++i)
|
for (auto i = data.RootAssets.Begin(); i.IsNotEnd(); ++i)
|
||||||
assetsQueue.Add(i->Item);
|
_assetsQueue.Add(i->Item);
|
||||||
|
|
||||||
// Iterate through the assets graph
|
// Iterate through the assets graph
|
||||||
AssetInfo assetInfo;
|
AssetInfo assetInfo;
|
||||||
Array<Guid> references;
|
while (_assetsQueue.HasItems())
|
||||||
Array<String> files;
|
|
||||||
while (assetsQueue.HasItems())
|
|
||||||
{
|
{
|
||||||
BUILD_STEP_CANCEL_CHECK;
|
BUILD_STEP_CANCEL_CHECK;
|
||||||
const Guid assetId = assetsQueue.Dequeue();
|
|
||||||
|
const auto assetId = _assetsQueue.Dequeue();
|
||||||
|
|
||||||
// Skip already processed or invalid assets
|
// Skip already processed or invalid assets
|
||||||
if (!assetId.IsValid()
|
if (!assetId.IsValid()
|
||||||
@@ -48,31 +69,14 @@ bool CollectAssetsStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load asset
|
// Load asset
|
||||||
AssetReference<Asset> asset = Content::LoadAsync<Asset>(assetId);
|
const auto asset = Content::LoadAsync<Asset>(assetId);
|
||||||
if (asset == nullptr)
|
if (asset == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Process that asset
|
||||||
LOG_STR(Info, asset->GetPath());
|
LOG_STR(Info, asset->GetPath());
|
||||||
data.Assets.Add(assetId);
|
data.Assets.Add(assetId);
|
||||||
|
Process(data, asset);
|
||||||
// Skip virtual/temporary assets
|
|
||||||
if (asset->IsVirtual())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Asset should have loaded data
|
|
||||||
if (asset->WaitForLoaded())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Gather asset references
|
|
||||||
references.Clear();
|
|
||||||
asset->Locker.Lock();
|
|
||||||
asset->GetReferences(references, files);
|
|
||||||
asset->Locker.Unlock();
|
|
||||||
assetsQueue.Add(references);
|
|
||||||
for (String& file : files)
|
|
||||||
{
|
|
||||||
if (file.HasChars())
|
|
||||||
data.Files.Add(MoveTemp(file));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.Stats.TotalAssets = data.Assets.Count();
|
data.Stats.TotalAssets = data.Assets.Count();
|
||||||
|
|||||||
@@ -12,7 +12,15 @@ class Asset;
|
|||||||
/// <seealso cref="GameCooker::BuildStep" />
|
/// <seealso cref="GameCooker::BuildStep" />
|
||||||
class CollectAssetsStep : public GameCooker::BuildStep
|
class CollectAssetsStep : public GameCooker::BuildStep
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Array<Guid> _assetsQueue;
|
||||||
|
Array<Guid> _references;
|
||||||
|
|
||||||
|
bool Process(CookingData& data, Asset* asset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// [BuildStep]
|
// [BuildStep]
|
||||||
bool Perform(CookingData& data) override;
|
bool Perform(CookingData& data) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -447,7 +447,6 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
|
|||||||
#if PLATFORM_TOOLS_WINDOWS
|
#if PLATFORM_TOOLS_WINDOWS
|
||||||
case BuildPlatform::Windows32:
|
case BuildPlatform::Windows32:
|
||||||
case BuildPlatform::Windows64:
|
case BuildPlatform::Windows64:
|
||||||
case BuildPlatform::WindowsARM64:
|
|
||||||
{
|
{
|
||||||
const char* platformDefineName = "PLATFORM_WINDOWS";
|
const char* platformDefineName = "PLATFORM_WINDOWS";
|
||||||
const auto settings = WindowsPlatformSettings::Get();
|
const auto settings = WindowsPlatformSettings::Get();
|
||||||
@@ -892,6 +891,7 @@ bool CookAssetsStep::Process(CookingData& data, CacheData& cache, JsonAssetBase*
|
|||||||
class PackageBuilder : public NonCopyable
|
class PackageBuilder : public NonCopyable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int32 _packageIndex;
|
int32 _packageIndex;
|
||||||
int32 MaxAssetsPerPackage;
|
int32 MaxAssetsPerPackage;
|
||||||
int32 MaxPackageSize;
|
int32 MaxPackageSize;
|
||||||
@@ -904,6 +904,7 @@ private:
|
|||||||
uint64 packagesSizeTotal;
|
uint64 packagesSizeTotal;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PackageBuilder" /> class.
|
/// Initializes a new instance of the <see cref="PackageBuilder" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -932,6 +933,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint64 GetPackagesSizeTotal() const
|
uint64 GetPackagesSizeTotal() const
|
||||||
{
|
{
|
||||||
return packagesSizeTotal;
|
return packagesSizeTotal;
|
||||||
@@ -1040,11 +1042,8 @@ bool CookAssetsStep::Perform(CookingData& data)
|
|||||||
float Step1ProgressEnd = 0.6f;
|
float Step1ProgressEnd = 0.6f;
|
||||||
String Step1Info = TEXT("Cooking assets");
|
String Step1Info = TEXT("Cooking assets");
|
||||||
float Step2ProgressStart = Step1ProgressEnd;
|
float Step2ProgressStart = Step1ProgressEnd;
|
||||||
float Step2ProgressEnd = 0.8f;
|
float Step2ProgressEnd = 0.9f;
|
||||||
String Step2Info = TEXT("Cooking files");
|
String Step2Info = TEXT("Packaging assets");
|
||||||
float Step3ProgressStart = Step2ProgressStart;
|
|
||||||
float Step3ProgressEnd = 0.9f;
|
|
||||||
String Step3Info = TEXT("Packaging assets");
|
|
||||||
|
|
||||||
data.StepProgress(TEXT("Loading build cache"), 0);
|
data.StepProgress(TEXT("Loading build cache"), 0);
|
||||||
|
|
||||||
@@ -1101,14 +1100,11 @@ bool CookAssetsStep::Perform(CookingData& data)
|
|||||||
#endif
|
#endif
|
||||||
int32 subStepIndex = 0;
|
int32 subStepIndex = 0;
|
||||||
AssetReference<Asset> assetRef;
|
AssetReference<Asset> assetRef;
|
||||||
assetRef.Unload.Bind([]
|
assetRef.Unload.Bind([]() { LOG(Error, "Asset gets unloaded while cooking it!"); Platform::Sleep(100); });
|
||||||
{
|
|
||||||
LOG(Error, "Asset got unloaded while cooking it!");
|
|
||||||
Platform::Sleep(100);
|
|
||||||
});
|
|
||||||
for (auto i = data.Assets.Begin(); i.IsNotEnd(); ++i)
|
for (auto i = data.Assets.Begin(); i.IsNotEnd(); ++i)
|
||||||
{
|
{
|
||||||
BUILD_STEP_CANCEL_CHECK;
|
BUILD_STEP_CANCEL_CHECK;
|
||||||
|
|
||||||
data.StepProgress(Step1Info, Math::Lerp(Step1ProgressStart, Step1ProgressEnd, static_cast<float>(subStepIndex++) / data.Assets.Count()));
|
data.StepProgress(Step1Info, Math::Lerp(Step1ProgressStart, Step1ProgressEnd, static_cast<float>(subStepIndex++) / data.Assets.Count()));
|
||||||
const Guid assetId = i->Item;
|
const Guid assetId = i->Item;
|
||||||
|
|
||||||
@@ -1188,35 +1184,6 @@ bool CookAssetsStep::Perform(CookingData& data)
|
|||||||
// Save build cache header
|
// Save build cache header
|
||||||
cache.Save(data);
|
cache.Save(data);
|
||||||
|
|
||||||
// Process all files
|
|
||||||
for (auto i = data.Files.Begin(); i.IsNotEnd(); ++i)
|
|
||||||
{
|
|
||||||
BUILD_STEP_CANCEL_CHECK;
|
|
||||||
data.StepProgress(Step2Info, Math::Lerp(Step2ProgressStart, Step2ProgressEnd, (float)subStepIndex++ / data.Files.Count()));
|
|
||||||
const String& filePath = i->Item;
|
|
||||||
|
|
||||||
// Calculate destination path
|
|
||||||
String cookedPath = data.DataOutputPath;
|
|
||||||
if (FileSystem::IsRelative(filePath))
|
|
||||||
cookedPath /= filePath;
|
|
||||||
else
|
|
||||||
cookedPath /= String(TEXT("Content")) / StringUtils::GetFileName(filePath);
|
|
||||||
|
|
||||||
// Copy file
|
|
||||||
if (!FileSystem::FileExists(cookedPath) || FileSystem::GetFileLastEditTime(cookedPath) >= FileSystem::GetFileLastEditTime(filePath))
|
|
||||||
{
|
|
||||||
if (FileSystem::CreateDirectory(StringUtils::GetDirectoryName(cookedPath)))
|
|
||||||
return true;
|
|
||||||
if (FileSystem::CopyFile(cookedPath, filePath))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count stats of file extension
|
|
||||||
auto& assetStats = data.Stats.AssetStats[FileSystem::GetExtension(cookedPath)];
|
|
||||||
assetStats.Count++;
|
|
||||||
assetStats.ContentSize += FileSystem::GetFileSize(cookedPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create build game header
|
// Create build game header
|
||||||
{
|
{
|
||||||
GameHeaderFlags gameFlags = GameHeaderFlags::None;
|
GameHeaderFlags gameFlags = GameHeaderFlags::None;
|
||||||
@@ -1262,11 +1229,13 @@ bool CookAssetsStep::Perform(CookingData& data)
|
|||||||
for (auto i = AssetsRegistry.Begin(); i.IsNotEnd(); ++i)
|
for (auto i = AssetsRegistry.Begin(); i.IsNotEnd(); ++i)
|
||||||
{
|
{
|
||||||
BUILD_STEP_CANCEL_CHECK;
|
BUILD_STEP_CANCEL_CHECK;
|
||||||
data.StepProgress(Step3Info, Math::Lerp(Step3ProgressStart, Step3ProgressEnd, (float)subStepIndex++ / AssetsRegistry.Count()));
|
|
||||||
|
data.StepProgress(Step2Info, Math::Lerp(Step2ProgressStart, Step2ProgressEnd, static_cast<float>(subStepIndex++) / AssetsRegistry.Count()));
|
||||||
const auto assetId = i->Key;
|
const auto assetId = i->Key;
|
||||||
|
|
||||||
String cookedFilePath;
|
String cookedFilePath;
|
||||||
cache.GetFilePath(assetId, cookedFilePath);
|
cache.GetFilePath(assetId, cookedFilePath);
|
||||||
|
|
||||||
if (!FileSystem::FileExists(cookedFilePath))
|
if (!FileSystem::FileExists(cookedFilePath))
|
||||||
{
|
{
|
||||||
LOG(Warning, "Missing cooked file for asset \'{0}\'", assetId);
|
LOG(Warning, "Missing cooked file for asset \'{0}\'", assetId);
|
||||||
@@ -1284,12 +1253,12 @@ bool CookAssetsStep::Perform(CookingData& data)
|
|||||||
return true;
|
return true;
|
||||||
for (auto& e : data.Stats.AssetStats)
|
for (auto& e : data.Stats.AssetStats)
|
||||||
e.Value.TypeName = e.Key;
|
e.Value.TypeName = e.Key;
|
||||||
data.Stats.ContentSize += packageBuilder.GetPackagesSizeTotal();
|
data.Stats.ContentSizeMB = static_cast<int32>(packageBuilder.GetPackagesSizeTotal() / (1024 * 1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
BUILD_STEP_CANCEL_CHECK;
|
BUILD_STEP_CANCEL_CHECK;
|
||||||
|
|
||||||
data.StepProgress(TEXT("Creating assets cache"), Step3ProgressEnd);
|
data.StepProgress(TEXT("Creating assets cache"), Step2ProgressEnd);
|
||||||
|
|
||||||
// Create asset paths mapping for the assets.
|
// Create asset paths mapping for the assets.
|
||||||
// Assets mapping is use to convert paths used in Content::Load(path) into the asset id.
|
// Assets mapping is use to convert paths used in Content::Load(path) into the asset id.
|
||||||
@@ -1322,7 +1291,7 @@ bool CookAssetsStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Print stats
|
// Print stats
|
||||||
LOG(Info, "Cooked {0} assets, total assets: {1}, total content packages size: {2} MB", data.Stats.CookedAssets, AssetsRegistry.Count(), (int32)(data.Stats.ContentSize / (1024 * 1024)));
|
LOG(Info, "Cooked {0} assets, total assets: {1}, total content packages size: {2} MB", data.Stats.CookedAssets, AssetsRegistry.Count(), data.Stats.ContentSizeMB);
|
||||||
{
|
{
|
||||||
Array<CookingData::AssetTypeStatistics> assetTypes;
|
Array<CookingData::AssetTypeStatistics> assetTypes;
|
||||||
data.Stats.AssetStats.GetValues(assetTypes);
|
data.Stats.AssetStats.GetValues(assetTypes);
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
{
|
{
|
||||||
case BuildPlatform::Windows32:
|
case BuildPlatform::Windows32:
|
||||||
case BuildPlatform::Windows64:
|
case BuildPlatform::Windows64:
|
||||||
case BuildPlatform::WindowsARM64:
|
|
||||||
canUseSystemDotnet = PLATFORM_TYPE == PlatformType::Windows;
|
canUseSystemDotnet = PLATFORM_TYPE == PlatformType::Windows;
|
||||||
break;
|
break;
|
||||||
case BuildPlatform::LinuxX64:
|
case BuildPlatform::LinuxX64:
|
||||||
@@ -160,20 +159,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: hostfxr for target platform should be copied from nuget package location: microsoft.netcore.app.runtime.<RID>/<VERSION>/runtimes/<RID>/native/hostfxr.dll
|
failed |= EditorUtilities::CopyDirectoryIfNewer(dstDotnet / TEXT("host/fxr") / version, srcDotnet / TEXT("host/fxr") / version, true);
|
||||||
String dstHostfxr = dstDotnet / TEXT("host/fxr") / version;
|
|
||||||
if (!FileSystem::DirectoryExists(dstHostfxr))
|
|
||||||
FileSystem::CreateDirectory(dstHostfxr);
|
|
||||||
const Char *platformName, *archName;
|
|
||||||
data.GetBuildPlatformName(platformName, archName);
|
|
||||||
if (data.Platform == BuildPlatform::Windows64 || data.Platform == BuildPlatform::WindowsARM64 || data.Platform == BuildPlatform::Windows32)
|
|
||||||
failed |= FileSystem::CopyFile(dstHostfxr / TEXT("hostfxr.dll"), depsRoot / TEXT("ThirdParty") / archName / TEXT("hostfxr.dll"));
|
|
||||||
else if (data.Platform == BuildPlatform::LinuxX64)
|
|
||||||
failed |= FileSystem::CopyFile(dstHostfxr / TEXT("hostfxr.so"), depsRoot / TEXT("ThirdParty") / archName / TEXT("hostfxr.so"));
|
|
||||||
else if (data.Platform == BuildPlatform::MacOSx64 || data.Platform == BuildPlatform::MacOSARM64)
|
|
||||||
failed |= FileSystem::CopyFile(dstHostfxr / TEXT("hostfxr.dylib"), depsRoot / TEXT("ThirdParty") / archName / TEXT("hostfxr.dylib"));
|
|
||||||
else
|
|
||||||
failed |= true;
|
|
||||||
failed |= EditorUtilities::CopyDirectoryIfNewer(dstDotnet / TEXT("shared/Microsoft.NETCore.App") / version, srcDotnet / TEXT("shared/Microsoft.NETCore.App") / version, true);
|
failed |= EditorUtilities::CopyDirectoryIfNewer(dstDotnet / TEXT("shared/Microsoft.NETCore.App") / version, srcDotnet / TEXT("shared/Microsoft.NETCore.App") / version, true);
|
||||||
}
|
}
|
||||||
if (failed)
|
if (failed)
|
||||||
|
|||||||
@@ -111,6 +111,11 @@ namespace FlaxEditor.CustomEditors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public PropertyNameLabel LinkedLabel;
|
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)
|
internal virtual void Initialize(CustomEditorPresenter presenter, LayoutElementsContainer layout, ValueContainer values)
|
||||||
{
|
{
|
||||||
_layout = layout;
|
_layout = layout;
|
||||||
@@ -377,10 +382,6 @@ namespace FlaxEditor.CustomEditors
|
|||||||
else if (Values.HasDefaultValue && CanRevertDefaultValue)
|
else if (Values.HasDefaultValue && CanRevertDefaultValue)
|
||||||
color = Color.Yellow * 0.8f;
|
color = Color.Yellow * 0.8f;
|
||||||
LinkedLabel.HighlightStripColor = color;
|
LinkedLabel.HighlightStripColor = color;
|
||||||
|
|
||||||
// Grey out deprecated members
|
|
||||||
if (Values.IsObsolete)
|
|
||||||
LinkedLabel.TextColor = LinkedLabel.TextColorHighlighted = FlaxEngine.GUI.Style.Current.ForegroundGrey;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,7 +664,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj == null || Values.Type.IsInstanceOfType(obj))
|
if ((obj == null && !Values.Type.IsValueType) || Values.Type.IsInstanceOfType(obj))
|
||||||
{
|
{
|
||||||
result = obj;
|
result = obj;
|
||||||
return true;
|
return true;
|
||||||
@@ -675,20 +676,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether can paste value from the system clipboard to the property value container.
|
/// Gets a value indicating whether can paste value from the system clipboard to the property value container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanPaste
|
public bool CanPaste => !string.IsNullOrEmpty(Clipboard.Text);
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return GetClipboardObject(out _, false);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the value from the system clipboard.
|
/// Sets the value from the system clipboard.
|
||||||
|
|||||||
@@ -67,19 +67,35 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
// Use default prefab instance as a reference for the editor
|
// Use default prefab instance as a reference for the editor
|
||||||
Values.SetReferenceValue(prefabInstance);
|
Values.SetReferenceValue(prefabInstance);
|
||||||
|
|
||||||
// Add some UI
|
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
|
||||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
{
|
||||||
panel.CustomControl.Height = 20.0f;
|
// Add some UI
|
||||||
panel.CustomControl.SlotsVertically = 1;
|
var panel = layout.CustomContainer<UniformGridPanel>();
|
||||||
panel.CustomControl.SlotsHorizontally = 2;
|
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
|
// Edit selected prefab asset
|
||||||
var selectPrefab = panel.Button("Select Prefab");
|
var editPrefab = panel.Button("Edit Prefab");
|
||||||
selectPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Select(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
|
// Viewing changes applied to this actor
|
||||||
var viewChanges = panel.Button("View Changes");
|
var viewChanges = panel.Button("View Changes");
|
||||||
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
||||||
|
}
|
||||||
|
|
||||||
// Link event to update editor on prefab apply
|
// Link event to update editor on prefab apply
|
||||||
_linkedPrefabId = prefab.ID;
|
_linkedPrefabId = prefab.ID;
|
||||||
|
|||||||
@@ -38,15 +38,15 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
_gizmoMode = new ClothPaintingGizmoMode();
|
_gizmoMode = new ClothPaintingGizmoMode();
|
||||||
|
|
||||||
var projectCache = Editor.Instance.ProjectCache;
|
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);
|
_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);
|
_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);
|
_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);
|
_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);
|
_gizmoMode.BrushStrength = JsonSerializer.Deserialize<float>(cachedBrushStrength);
|
||||||
|
|
||||||
gizmos.AddMode(_gizmoMode);
|
gizmos.AddMode(_gizmoMode);
|
||||||
|
|||||||
@@ -880,6 +880,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
|
|
||||||
group.Panel.HeaderTextMargin = new Margin(scriptDrag.Right - 12, 15, 2, 2);
|
group.Panel.HeaderTextMargin = new Margin(scriptDrag.Right - 12, 15, 2, 2);
|
||||||
group.Object(values, editor);
|
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
|
// Scripts arrange bar
|
||||||
dragBar = layout.Custom<ScriptArrangeBar>();
|
dragBar = layout.Custom<ScriptArrangeBar>();
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
base.Initialize(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
|
// Override colors
|
||||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||||
@@ -66,6 +73,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
base.Initialize(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
|
// Override colors
|
||||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
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");
|
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
|
// Override colors
|
||||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using FlaxEditor.Content;
|
|||||||
using FlaxEditor.GUI;
|
using FlaxEditor.GUI;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.CustomEditors.Editors
|
namespace FlaxEditor.CustomEditors.Editors
|
||||||
@@ -51,6 +50,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
if (HasDifferentTypes)
|
if (HasDifferentTypes)
|
||||||
return;
|
return;
|
||||||
Picker = layout.Custom<AssetPicker>().CustomControl;
|
Picker = layout.Custom<AssetPicker>().CustomControl;
|
||||||
|
|
||||||
var value = Values[0];
|
var value = Values[0];
|
||||||
_valueType = Values.Type.Type != typeof(object) || value == null ? Values.Type : TypeUtils.GetObjectType(value);
|
_valueType = Values.Type.Type != typeof(object) || value == null ? Values.Type : TypeUtils.GetObjectType(value);
|
||||||
var assetType = _valueType;
|
var assetType = _valueType;
|
||||||
@@ -58,8 +58,37 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
assetType = new ScriptType(typeof(Asset));
|
assetType = new ScriptType(typeof(Asset));
|
||||||
else if (_valueType.Type != null && _valueType.Type.Name == typeof(JsonAssetReference<>).Name)
|
else if (_valueType.Type != null && _valueType.Type.Name == typeof(JsonAssetReference<>).Name)
|
||||||
assetType = new ScriptType(_valueType.Type.GenericTypeArguments[0]);
|
assetType = new ScriptType(_valueType.Type.GenericTypeArguments[0]);
|
||||||
|
|
||||||
|
float height = 48;
|
||||||
|
var attributes = Values.GetAttributes();
|
||||||
|
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
|
||||||
|
if (assetReference != null)
|
||||||
|
{
|
||||||
|
if (assetReference.UseSmallPicker)
|
||||||
|
height = 32;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(assetReference.TypeName))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (assetReference.TypeName.Length > 1 && assetReference.TypeName[0] == '.')
|
||||||
|
{
|
||||||
|
// Generic file picker
|
||||||
|
assetType = ScriptType.Null;
|
||||||
|
Picker.Validator.FileExtension = assetReference.TypeName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var customType = TypeUtils.GetType(assetReference.TypeName);
|
||||||
|
if (customType != ScriptType.Null)
|
||||||
|
assetType = customType;
|
||||||
|
else if (!Content.Settings.GameSettings.OptionalPlatformSettings.Contains(assetReference.TypeName))
|
||||||
|
Debug.LogWarning(string.Format("Unknown asset type '{0}' to use for asset picker filter.", assetReference.TypeName));
|
||||||
|
else
|
||||||
|
assetType = ScriptType.Void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Picker.Validator.AssetType = assetType;
|
Picker.Validator.AssetType = assetType;
|
||||||
ApplyAssetReferenceAttribute(Values, out var height, Picker.Validator);
|
|
||||||
Picker.Height = height;
|
Picker.Height = height;
|
||||||
Picker.SelectedItemChanged += OnSelectedItemChanged;
|
Picker.SelectedItemChanged += OnSelectedItemChanged;
|
||||||
}
|
}
|
||||||
@@ -86,37 +115,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
SetValue(Picker.Validator.SelectedAsset);
|
SetValue(Picker.Validator.SelectedAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ApplyAssetReferenceAttribute(ValueContainer values, out float height, AssetPickerValidator validator)
|
|
||||||
{
|
|
||||||
height = 48;
|
|
||||||
var attributes = values.GetAttributes();
|
|
||||||
var assetReference = (AssetReferenceAttribute)attributes?.FirstOrDefault(x => x is AssetReferenceAttribute);
|
|
||||||
if (assetReference != null)
|
|
||||||
{
|
|
||||||
if (assetReference.UseSmallPicker)
|
|
||||||
height = 32;
|
|
||||||
if (string.IsNullOrEmpty(assetReference.TypeName))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if (assetReference.TypeName.Length > 1 && assetReference.TypeName[0] == '.')
|
|
||||||
{
|
|
||||||
// Generic file picker
|
|
||||||
validator.AssetType = ScriptType.Null;
|
|
||||||
validator.FileExtension = assetReference.TypeName;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var customType = TypeUtils.GetType(assetReference.TypeName);
|
|
||||||
if (customType != ScriptType.Null)
|
|
||||||
validator.AssetType = customType;
|
|
||||||
else if (!Content.Settings.GameSettings.OptionalPlatformSettings.Contains(assetReference.TypeName))
|
|
||||||
Debug.LogWarning(string.Format("Unknown asset type '{0}' to use for asset picker filter.", assetReference.TypeName));
|
|
||||||
else
|
|
||||||
validator.AssetType = ScriptType.Void;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Refresh()
|
public override void Refresh()
|
||||||
{
|
{
|
||||||
@@ -142,155 +140,4 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default implementation of the inspector used to edit reference to the files via path (absolute or relative to the project).
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>Supports editing reference to the asset via path using various containers: <see cref="Asset"/> or <see cref="AssetItem"/> or <see cref="System.String"/>.</remarks>
|
|
||||||
public class FilePathEditor : CustomEditor
|
|
||||||
{
|
|
||||||
private sealed class TextBoxWithPicker : TextBox
|
|
||||||
{
|
|
||||||
private const float DropdownIconMargin = 3.0f;
|
|
||||||
private const float DropdownIconSize = 12.0f;
|
|
||||||
private Rectangle DropdownRect => new Rectangle(Width - DropdownIconSize - DropdownIconMargin, DropdownIconMargin, DropdownIconSize, DropdownIconSize);
|
|
||||||
|
|
||||||
public Action ShowPicker;
|
|
||||||
|
|
||||||
public override void Draw()
|
|
||||||
{
|
|
||||||
base.Draw();
|
|
||||||
|
|
||||||
var style = FlaxEngine.GUI.Style.Current;
|
|
||||||
var dropdownRect = DropdownRect;
|
|
||||||
Render2D.DrawSprite(style.ArrowDown, dropdownRect, Enabled ? (DropdownRect.Contains(PointFromWindow(RootWindow.MousePosition)) ? style.BorderSelected : style.Foreground) : style.ForegroundDisabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
|
||||||
{
|
|
||||||
if (DropdownRect.Contains(ref location))
|
|
||||||
{
|
|
||||||
Focus();
|
|
||||||
ShowPicker();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnMouseDown(location, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnMouseMove(Float2 location)
|
|
||||||
{
|
|
||||||
base.OnMouseMove(location);
|
|
||||||
|
|
||||||
if (DropdownRect.Contains(ref location))
|
|
||||||
Cursor = CursorType.Default;
|
|
||||||
else
|
|
||||||
Cursor = CursorType.IBeam;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Rectangle TextRectangle
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var result = base.TextRectangle;
|
|
||||||
result.Size.X -= DropdownIconSize + DropdownIconMargin * 2;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Rectangle TextClipRectangle
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var result = base.TextClipRectangle;
|
|
||||||
result.Size.X -= DropdownIconSize + DropdownIconMargin * 2;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextBoxWithPicker _textBox;
|
|
||||||
private AssetPickerValidator _validator;
|
|
||||||
private bool _isRefreshing;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override DisplayStyle Style => DisplayStyle.Inline;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
|
||||||
{
|
|
||||||
if (HasDifferentTypes)
|
|
||||||
return;
|
|
||||||
_textBox = layout.Custom<TextBoxWithPicker>().CustomControl;
|
|
||||||
_textBox.ShowPicker = OnShowPicker;
|
|
||||||
_textBox.EditEnd += OnEditEnd;
|
|
||||||
_validator = new AssetPickerValidator(ScriptType.Null);
|
|
||||||
AssetRefEditor.ApplyAssetReferenceAttribute(Values, out _, _validator);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnShowPicker()
|
|
||||||
{
|
|
||||||
if (_validator.AssetType != ScriptType.Null)
|
|
||||||
AssetSearchPopup.Show(_textBox, _textBox.BottomLeft, _validator.IsValid, SetPickerPath);
|
|
||||||
else
|
|
||||||
ContentSearchPopup.Show(_textBox, _textBox.BottomLeft, _validator.IsValid, SetPickerPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetPickerPath(ContentItem item)
|
|
||||||
{
|
|
||||||
var path = Utilities.Utils.ToPathProject(item.Path);
|
|
||||||
SetPath(path);
|
|
||||||
|
|
||||||
_isRefreshing = true;
|
|
||||||
_textBox.Defocus();
|
|
||||||
_textBox.Text = path;
|
|
||||||
_isRefreshing = false;
|
|
||||||
|
|
||||||
_textBox.RootWindow.Focus();
|
|
||||||
_textBox.Focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEditEnd()
|
|
||||||
{
|
|
||||||
SetPath(_textBox.Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetPath()
|
|
||||||
{
|
|
||||||
var value = Values[0];
|
|
||||||
if (value is AssetItem assetItem)
|
|
||||||
return Utilities.Utils.ToPathProject(assetItem.Path);
|
|
||||||
if (value is Asset asset)
|
|
||||||
return Utilities.Utils.ToPathProject(asset.Path);
|
|
||||||
if (value is string str)
|
|
||||||
return str;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SetPath(string path)
|
|
||||||
{
|
|
||||||
if (_isRefreshing)
|
|
||||||
return;
|
|
||||||
var value = Values[0];
|
|
||||||
if (value is AssetItem)
|
|
||||||
SetValue(Editor.Instance.ContentDatabase.Find(Utilities.Utils.ToPathAbsolute(path)));
|
|
||||||
else if (value is Asset)
|
|
||||||
SetValue(FlaxEngine.Content.LoadAsync(path));
|
|
||||||
else if (value is string)
|
|
||||||
SetValue(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Refresh()
|
|
||||||
{
|
|
||||||
base.Refresh();
|
|
||||||
|
|
||||||
if (!HasDifferentValues)
|
|
||||||
{
|
|
||||||
_isRefreshing = true;
|
|
||||||
_textBox.Text = GetPath();
|
|
||||||
_isRefreshing = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly int Index;
|
public readonly int Index;
|
||||||
|
|
||||||
|
private Rectangle _arrangeButtonRect;
|
||||||
|
private bool _arrangeButtonInUse;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="CollectionItemLabel"/> class.
|
/// Initializes a new instance of the <see cref="CollectionItemLabel"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -50,6 +53,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
Index = index;
|
Index = index;
|
||||||
|
|
||||||
SetupContextMenu += OnSetupContextMenu;
|
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)
|
private void OnSetupContextMenu(PropertyNameLabel label, ContextMenu menu, CustomEditor linkedEditor)
|
||||||
@@ -71,6 +80,107 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
b.Enabled = !Editor._readOnly;
|
b.Enabled = !Editor._readOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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()
|
private void OnMoveUpClicked()
|
||||||
{
|
{
|
||||||
Editor.Move(Index, Index - 1);
|
Editor.Move(Index, Index - 1);
|
||||||
@@ -106,6 +216,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private bool _canReorder = true;
|
private bool _canReorder = true;
|
||||||
|
|
||||||
|
private Rectangle _arrangeButtonRect;
|
||||||
|
private bool _arrangeButtonInUse;
|
||||||
|
|
||||||
public void Setup(CollectionEditor editor, int index, bool canReorder = true)
|
public void Setup(CollectionEditor editor, int index, bool canReorder = true)
|
||||||
{
|
{
|
||||||
HeaderHeight = 18;
|
HeaderHeight = 18;
|
||||||
@@ -123,10 +236,92 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
MouseButtonRightClicked += OnMouseButtonRightClicked;
|
MouseButtonRightClicked += OnMouseButtonRightClicked;
|
||||||
if (_canReorder)
|
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)
|
private void OnMouseButtonRightClicked(DropPanel panel, Float2 location)
|
||||||
{
|
{
|
||||||
if (LinkedEditor == null)
|
if (LinkedEditor == null)
|
||||||
@@ -227,7 +422,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
||||||
if (collection != null)
|
if (collection != null)
|
||||||
{
|
{
|
||||||
_canResize = !collection.ReadOnly;
|
_canResize = collection.CanResize;
|
||||||
_readOnly = collection.ReadOnly;
|
_readOnly = collection.ReadOnly;
|
||||||
_minCount = collection.MinCount;
|
_minCount = collection.MinCount;
|
||||||
_maxCount = collection.MaxCount;
|
_maxCount = collection.MaxCount;
|
||||||
@@ -324,7 +519,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
(elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) ||
|
(elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) ||
|
||||||
elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
|
elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
|
||||||
elementType.Equals(new ScriptType(typeof(SettingsBase)));
|
elementType.Equals(new ScriptType(typeof(SettingsBase)));
|
||||||
|
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
{
|
{
|
||||||
// Apply spacing
|
// Apply spacing
|
||||||
@@ -440,6 +634,39 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
SetValue(cloned);
|
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>
|
/// <summary>
|
||||||
/// Removes the item at the specified index. It supports undo.
|
/// Removes the item at the specified index. It supports undo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
||||||
if (collection != null)
|
if (collection != null)
|
||||||
{
|
{
|
||||||
|
_canEditKeys &= collection.CanReorderItems;
|
||||||
_readOnly = collection.ReadOnly;
|
_readOnly = collection.ReadOnly;
|
||||||
_notNullItems = collection.NotNullItems;
|
_notNullItems = collection.NotNullItems;
|
||||||
if (collection.BackgroundColor.HasValue)
|
if (collection.BackgroundColor.HasValue)
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Draw info
|
// 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
|
// Draw picker button
|
||||||
|
|||||||
@@ -474,32 +474,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
}
|
}
|
||||||
if (layout.Editors.Count != 0)
|
if (layout.Editors.Count != 0)
|
||||||
{
|
{
|
||||||
var sb = Clipboard.Text;
|
return !string.IsNullOrEmpty(Clipboard.Text);
|
||||||
if (!string.IsNullOrEmpty(sb))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var data = JsonSerializer.Deserialize<string[]>(sb);
|
|
||||||
if (data == null || data.Length != layout.Editors.Count)
|
|
||||||
return false;
|
|
||||||
for (var i = 0; i < layout.Editors.Count; i++)
|
|
||||||
{
|
|
||||||
Clipboard.Text = data[i];
|
|
||||||
if (!layout.Editors[i].CanPaste)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
Clipboard.Text = sb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (layout.Children.Any(x => x is LayoutElementsContainer))
|
if (layout.Children.Any(x => x is LayoutElementsContainer))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
new OptionType("Linear Gradient", typeof(LinearGradientBrush)),
|
new OptionType("Linear Gradient", typeof(LinearGradientBrush)),
|
||||||
new OptionType("Texture 9-Slicing", typeof(Texture9SlicingBrush)),
|
new OptionType("Texture 9-Slicing", typeof(Texture9SlicingBrush)),
|
||||||
new OptionType("Sprite 9-Slicing", typeof(Sprite9SlicingBrush)),
|
new OptionType("Sprite 9-Slicing", typeof(Sprite9SlicingBrush)),
|
||||||
new OptionType("Video", typeof(VideoBrush)),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,22 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
_element.Value = asInt;
|
_element.Value = asInt;
|
||||||
else if (value is float asFloat)
|
else if (value is float asFloat)
|
||||||
_element.Value = (int)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
|
else
|
||||||
throw new Exception(string.Format("Invalid value type {0}.", value?.GetType().ToString() ?? "<null>"));
|
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);
|
protected abstract ulong GetValue(object value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the value from long.
|
/// Sets the value from long.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The value from editor.</param>
|
/// <param name="value">The value from editor.</param>
|
||||||
/// <returns>The value to object.</returns>
|
/// <returns>The value to object.</returns>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
if (watermarkAttribute is WatermarkAttribute watermark)
|
if (watermarkAttribute is WatermarkAttribute watermark)
|
||||||
{
|
{
|
||||||
_watermarkText = watermark.WatermarkText;
|
_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;
|
_watermarkColor = watermarkColor;
|
||||||
_element.TextBox.WatermarkText = watermark.WatermarkText;
|
_element.TextBox.WatermarkText = watermark.WatermarkText;
|
||||||
_element.TextBox.WatermarkTextColor = watermarkColor;
|
_element.TextBox.WatermarkTextColor = watermarkColor;
|
||||||
|
|||||||
@@ -318,7 +318,9 @@ namespace FlaxEditor.CustomEditors
|
|||||||
if (header.FontSize > 0)
|
if (header.FontSize > 0)
|
||||||
element.Label.Font = new FontReference(element.Label.Font.Font, header.FontSize);
|
element.Label.Font = new FontReference(element.Label.Font.Font, header.FontSize);
|
||||||
if (header.Color > 0)
|
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;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,11 +139,6 @@ namespace FlaxEditor.CustomEditors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsArray => Type != ScriptType.Null && Type.IsArray;
|
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>
|
/// <summary>
|
||||||
/// Gets the values types array (without duplicates).
|
/// Gets the values types array (without duplicates).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -165,7 +160,6 @@ namespace FlaxEditor.CustomEditors
|
|||||||
{
|
{
|
||||||
Info = info;
|
Info = info;
|
||||||
Type = Info.ValueType;
|
Type = Info.ValueType;
|
||||||
IsObsolete = Info.HasAttribute(typeof(ObsoleteAttribute), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -247,6 +247,11 @@ namespace FlaxEditor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action PlayModeEnd;
|
public event Action PlayModeEnd;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired on Editor update
|
||||||
|
/// </summary>
|
||||||
|
public event Action EditorUpdate;
|
||||||
|
|
||||||
internal Editor()
|
internal Editor()
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
@@ -330,7 +335,7 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
case GeneralOptions.StartupSceneModes.LastOpened:
|
case GeneralOptions.StartupSceneModes.LastOpened:
|
||||||
{
|
{
|
||||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName))
|
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
|
||||||
{
|
{
|
||||||
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
||||||
foreach (var scene in lastScenes)
|
foreach (var scene in lastScenes)
|
||||||
@@ -442,7 +447,7 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
case GeneralOptions.StartupSceneModes.LastOpened:
|
case GeneralOptions.StartupSceneModes.LastOpened:
|
||||||
{
|
{
|
||||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName))
|
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
|
||||||
{
|
{
|
||||||
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
||||||
foreach (var sceneId in lastScenes)
|
foreach (var sceneId in lastScenes)
|
||||||
@@ -459,7 +464,7 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore view
|
// Restore view
|
||||||
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out var lastSceneSpawnName))
|
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out string lastSceneSpawnName))
|
||||||
Windows.EditWin.Viewport.ViewRay = JsonSerializer.Deserialize<Ray>(lastSceneSpawnName);
|
Windows.EditWin.Viewport.ViewRay = JsonSerializer.Deserialize<Ray>(lastSceneSpawnName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -485,6 +490,8 @@ namespace FlaxEditor
|
|||||||
{
|
{
|
||||||
StateMachine.CurrentState.UpdateFPS();
|
StateMachine.CurrentState.UpdateFPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditorUpdate?.Invoke();
|
||||||
|
|
||||||
// Update modules
|
// Update modules
|
||||||
for (int i = 0; i < _modules.Count; i++)
|
for (int i = 0; i < _modules.Count; i++)
|
||||||
@@ -1364,6 +1371,7 @@ namespace FlaxEditor
|
|||||||
public byte AutoReloadScriptsOnMainWindowFocus;
|
public byte AutoReloadScriptsOnMainWindowFocus;
|
||||||
public byte ForceScriptCompilationOnStartup;
|
public byte ForceScriptCompilationOnStartup;
|
||||||
public byte UseAssetImportPathRelative;
|
public byte UseAssetImportPathRelative;
|
||||||
|
public byte EnableParticlesPreview;
|
||||||
public byte AutoRebuildCSG;
|
public byte AutoRebuildCSG;
|
||||||
public float AutoRebuildCSGTimeoutMs;
|
public float AutoRebuildCSGTimeoutMs;
|
||||||
public byte AutoRebuildNavMesh;
|
public byte AutoRebuildNavMesh;
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ using System.IO;
|
|||||||
using FlaxEditor.Content;
|
using FlaxEditor.Content;
|
||||||
using FlaxEditor.GUI.Drag;
|
using FlaxEditor.GUI.Drag;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
using FlaxEngine.Utilities;
|
||||||
|
|
||||||
namespace FlaxEditor.GUI
|
namespace FlaxEditor.GUI
|
||||||
{
|
{
|
||||||
@@ -103,9 +105,9 @@ namespace FlaxEditor.GUI
|
|||||||
|
|
||||||
private Rectangle Button1Rect => new Rectangle(Height + ButtonsOffset, 0, ButtonsSize, ButtonsSize);
|
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 />
|
/// <inheritdoc />
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
@@ -147,6 +149,13 @@ namespace FlaxEditor.GUI
|
|||||||
style.Foreground,
|
style.Foreground,
|
||||||
TextAlignment.Near,
|
TextAlignment.Near,
|
||||||
TextAlignment.Center);
|
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)
|
// Check if has no item but has an asset (eg. virtual asset)
|
||||||
@@ -169,6 +178,13 @@ namespace FlaxEditor.GUI
|
|||||||
style.Foreground,
|
style.Foreground,
|
||||||
TextAlignment.Near,
|
TextAlignment.Near,
|
||||||
TextAlignment.Center);
|
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
|
else
|
||||||
@@ -176,6 +192,24 @@ namespace FlaxEditor.GUI
|
|||||||
// No element selected
|
// No element selected
|
||||||
Render2D.FillRectangle(iconRect, style.BackgroundNormal);
|
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);
|
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
|
// Check if drag is over
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
namespace FlaxEditor.GUI
|
namespace FlaxEditor.GUI
|
||||||
{
|
{
|
||||||
@@ -43,10 +44,20 @@ namespace FlaxEditor.GUI
|
|||||||
public Color TitleColor = Color.White;
|
public Color TitleColor = Color.White;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The column title background background.
|
/// The column title background color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Color TitleBackgroundColor = Color.Brown;
|
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>
|
/// <summary>
|
||||||
/// The minimum size (in pixels) of the column.
|
/// The minimum size (in pixels) of the column.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
#define USE_IS_FOREGROUND
|
#define USE_IS_FOREGROUND
|
||||||
#else
|
#else
|
||||||
#endif
|
#endif
|
||||||
|
#if PLATFORM_SDL
|
||||||
|
#define USE_SDL_WORKAROUNDS
|
||||||
|
#endif
|
||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -111,7 +114,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the empty menu popup o na screen.
|
/// Shows the empty menu popup on a screen.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="control">The target control.</param>
|
/// <param name="control">The target control.</param>
|
||||||
/// <param name="area">The target control area to cover.</param>
|
/// <param name="area">The target control area to cover.</param>
|
||||||
@@ -215,7 +218,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
desc.AllowMaximize = false;
|
desc.AllowMaximize = false;
|
||||||
desc.AllowDragAndDrop = false;
|
desc.AllowDragAndDrop = false;
|
||||||
desc.IsTopmost = true;
|
desc.IsTopmost = true;
|
||||||
desc.IsRegularWindow = false;
|
desc.Type = WindowType.Utility;
|
||||||
desc.HasSizingFrame = false;
|
desc.HasSizingFrame = false;
|
||||||
OnWindowCreating(ref desc);
|
OnWindowCreating(ref desc);
|
||||||
_window = Platform.CreateWindow(ref desc);
|
_window = Platform.CreateWindow(ref desc);
|
||||||
@@ -228,8 +231,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
|
|
||||||
// Show
|
// Show
|
||||||
Visible = true;
|
Visible = true;
|
||||||
if (_window == null)
|
|
||||||
return;
|
|
||||||
_window.Show();
|
_window.Show();
|
||||||
PerformLayout();
|
PerformLayout();
|
||||||
_previouslyFocused = parentWin.FocusedControl;
|
_previouslyFocused = parentWin.FocusedControl;
|
||||||
@@ -378,6 +379,11 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_SDL_WORKAROUNDS
|
||||||
|
private void OnWindowGotFocus()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#else
|
||||||
private void OnWindowGotFocus()
|
private void OnWindowGotFocus()
|
||||||
{
|
{
|
||||||
var child = _childCM;
|
var child = _childCM;
|
||||||
@@ -391,6 +397,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private void OnWindowLostFocus()
|
private void OnWindowLostFocus()
|
||||||
{
|
{
|
||||||
@@ -489,7 +496,12 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
// Let root context menu to check if none of the popup windows
|
// Let root context menu to check if none of the popup windows
|
||||||
if (_parentCM == null && !IsForeground)
|
if (_parentCM == null && !IsForeground)
|
||||||
{
|
{
|
||||||
|
#if USE_SDL_WORKAROUNDS
|
||||||
|
if (!IsMouseOver)
|
||||||
|
Hide();
|
||||||
|
#else
|
||||||
Hide();
|
Hide();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
private bool _disableEvents;
|
private bool _disableEvents;
|
||||||
private bool _useDynamicEditing;
|
private bool _useDynamicEditing;
|
||||||
private bool _activeEyedropper;
|
private bool _activeEyedropper;
|
||||||
|
private bool _canPassLastChangeEvent = true;
|
||||||
private ColorValueBox.ColorPickerEvent _onChanged;
|
private ColorValueBox.ColorPickerEvent _onChanged;
|
||||||
private ColorValueBox.ColorPickerClosedEvent _onClosed;
|
private ColorValueBox.ColorPickerClosedEvent _onClosed;
|
||||||
|
|
||||||
@@ -119,10 +120,8 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
_onClosed = pickerClosed;
|
_onClosed = pickerClosed;
|
||||||
|
|
||||||
// Get saved colors if they exist
|
// 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);
|
_savedColors = JsonSerializer.Deserialize<List<Color>>(savedColors);
|
||||||
}
|
|
||||||
|
|
||||||
// Selector
|
// Selector
|
||||||
_cSelector = new ColorSelectorWithSliders(180, 18)
|
_cSelector = new ColorSelectorWithSliders(180, 18)
|
||||||
@@ -382,7 +381,7 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
{
|
{
|
||||||
for (int j = 0; j < numVer; j++)
|
for (int j = 0; j < numVer; j++)
|
||||||
{
|
{
|
||||||
if ((i + j) % 2 == 0 )
|
if ((i + j) % 2 == 0)
|
||||||
{
|
{
|
||||||
var rect = new Rectangle(newRect.X + smallRectSize * i, newRect.Y + smallRectSize * j, new Float2(smallRectSize));
|
var rect = new Rectangle(newRect.X + smallRectSize * i, newRect.Y + smallRectSize * j, new Float2(smallRectSize));
|
||||||
Render2D.FillRectangle(rect, Color.Gray);
|
Render2D.FillRectangle(rect, Color.Gray);
|
||||||
@@ -397,7 +396,7 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
{
|
{
|
||||||
// Auto cancel on lost focus
|
// Auto cancel on lost focus
|
||||||
#if !PLATFORM_LINUX
|
#if !PLATFORM_LINUX
|
||||||
((WindowRootControl)Root).Window.LostFocus += OnCancel;
|
((WindowRootControl)Root).Window.LostFocus += OnWindowLostFocus;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
base.OnShow();
|
base.OnShow();
|
||||||
@@ -506,7 +505,7 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
BackgroundColorHighlighted = savedColor,
|
BackgroundColorHighlighted = savedColor,
|
||||||
BackgroundColorSelected = savedColor.RGBMultiplied(0.8f),
|
BackgroundColorSelected = savedColor.RGBMultiplied(0.8f),
|
||||||
};
|
};
|
||||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
|
||||||
_savedColorButtons.Add(savedColorButton);
|
_savedColorButtons.Add(savedColorButton);
|
||||||
}
|
}
|
||||||
if (_savedColors.Count < 8)
|
if (_savedColors.Count < 8)
|
||||||
@@ -518,11 +517,24 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
TooltipText = "Save Color.",
|
TooltipText = "Save Color.",
|
||||||
Tag = null,
|
Tag = null,
|
||||||
};
|
};
|
||||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
|
||||||
_savedColorButtons.Add(savedColorButton);
|
_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 />
|
/// <inheritdoc />
|
||||||
public override void OnSubmit()
|
public override void OnSubmit()
|
||||||
{
|
{
|
||||||
@@ -547,8 +559,9 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
_disableEvents = true;
|
_disableEvents = true;
|
||||||
|
|
||||||
// Restore color if modified
|
// Restore color if modified
|
||||||
if (_useDynamicEditing && _initialValue != _value)
|
if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent)
|
||||||
{
|
{
|
||||||
|
_canPassLastChangeEvent = false;
|
||||||
_onChanged?.Invoke(_initialValue, false);
|
_onChanged?.Invoke(_initialValue, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,9 +67,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
Proxy.Window.MouseUp += OnMouseUp;
|
Proxy.Window.MouseUp += OnMouseUp;
|
||||||
Proxy.Window.MouseMove += OnMouseMove;
|
Proxy.Window.MouseMove += OnMouseMove;
|
||||||
Proxy.Window.LostFocus += OnLostFocus;
|
Proxy.Window.LostFocus += OnLostFocus;
|
||||||
|
_toMove.Window.Window.MouseUp += OnMouseUp; // Intercept the drag release mouse event from source window
|
||||||
// Start tracking mouse
|
|
||||||
Proxy.Window.StartTrackingMouse(false);
|
|
||||||
|
|
||||||
// Update window GUI
|
// Update window GUI
|
||||||
Proxy.Window.GUI.PerformLayout();
|
Proxy.Window.GUI.PerformLayout();
|
||||||
@@ -77,13 +75,16 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
// Update rectangles
|
// Update rectangles
|
||||||
UpdateRects();
|
UpdateRects();
|
||||||
|
|
||||||
// Hide base window
|
|
||||||
window.Hide();
|
|
||||||
|
|
||||||
// Enable hit window presentation
|
// Enable hit window presentation
|
||||||
Proxy.Window.RenderingEnabled = true;
|
Proxy.Window.RenderingEnabled = true;
|
||||||
Proxy.Window.Show();
|
Proxy.Window.Show();
|
||||||
Proxy.Window.Focus();
|
Proxy.Window.Focus();
|
||||||
|
|
||||||
|
// Hide base window
|
||||||
|
window.Hide();
|
||||||
|
|
||||||
|
// Start tracking mouse
|
||||||
|
Proxy.Window.StartTrackingMouse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -101,6 +102,8 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
Proxy.Window.MouseUp -= OnMouseUp;
|
Proxy.Window.MouseUp -= OnMouseUp;
|
||||||
Proxy.Window.MouseMove -= OnMouseMove;
|
Proxy.Window.MouseMove -= OnMouseMove;
|
||||||
Proxy.Window.LostFocus -= OnLostFocus;
|
Proxy.Window.LostFocus -= OnLostFocus;
|
||||||
|
if (_toMove?.Window?.Window)
|
||||||
|
_toMove.Window.Window.MouseUp -= OnMouseUp;
|
||||||
|
|
||||||
// Hide the proxy
|
// Hide the proxy
|
||||||
Proxy.Hide();
|
Proxy.Hide();
|
||||||
@@ -438,7 +441,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.AllowMinimize = false;
|
settings.AllowMinimize = false;
|
||||||
settings.HasBorder = false;
|
settings.HasBorder = false;
|
||||||
settings.HasSizingFrame = false;
|
settings.HasSizingFrame = false;
|
||||||
settings.IsRegularWindow = false;
|
settings.Type = WindowType.Utility;
|
||||||
settings.SupportsTransparency = true;
|
settings.SupportsTransparency = true;
|
||||||
settings.ShowInTaskbar = false;
|
settings.ShowInTaskbar = false;
|
||||||
settings.ShowAfterFirstPaint = false;
|
settings.ShowAfterFirstPaint = false;
|
||||||
@@ -470,7 +473,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.AllowMinimize = false;
|
settings.AllowMinimize = false;
|
||||||
settings.HasBorder = false;
|
settings.HasBorder = false;
|
||||||
settings.HasSizingFrame = false;
|
settings.HasSizingFrame = false;
|
||||||
settings.IsRegularWindow = false;
|
settings.Type = WindowType.Utility;
|
||||||
settings.SupportsTransparency = true;
|
settings.SupportsTransparency = true;
|
||||||
settings.ShowInTaskbar = false;
|
settings.ShowInTaskbar = false;
|
||||||
settings.ActivateWhenFirstShown = false;
|
settings.ActivateWhenFirstShown = false;
|
||||||
|
|||||||
@@ -629,7 +629,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
|
|
||||||
internal void MoveTabRight(int index)
|
internal void MoveTabRight(int index)
|
||||||
{
|
{
|
||||||
if (index < _tabs.Count - 2)
|
if (index < _tabs.Count - 1)
|
||||||
{
|
{
|
||||||
var tab = _tabs[index];
|
var tab = _tabs[index];
|
||||||
_tabs.RemoveAt(index);
|
_tabs.RemoveAt(index);
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
public DockWindow StartDragAsyncWindow;
|
public DockWindow StartDragAsyncWindow;
|
||||||
|
|
||||||
private Rectangle HeaderRectangle => new Rectangle(0, 0, Width, DockPanel.DefaultHeaderHeight);
|
private Rectangle HeaderRectangle => new Rectangle(0, 0, Width, DockPanel.DefaultHeaderHeight);
|
||||||
|
private bool IsSingleFloatingWindow => _panel.TabsCount == 1 && _panel.IsFloating && _panel.ChildPanelsCount == 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="DockPanelProxy"/> class.
|
/// Initializes a new instance of the <see cref="DockPanelProxy"/> class.
|
||||||
@@ -187,6 +188,10 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
var headerRect = HeaderRectangle;
|
var headerRect = HeaderRectangle;
|
||||||
var tabsCount = _panel.TabsCount;
|
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
|
// Check if has only one window docked
|
||||||
if (tabsCount == 1)
|
if (tabsCount == 1)
|
||||||
{
|
{
|
||||||
@@ -321,6 +326,9 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
|
if (IsSingleFloatingWindow)
|
||||||
|
return base.OnMouseDoubleClick(location, button);
|
||||||
|
|
||||||
// Maximize/restore on double click
|
// Maximize/restore on double click
|
||||||
var tab = GetTabAtPos(location, out _);
|
var tab = GetTabAtPos(location, out _);
|
||||||
var rootWindow = tab?.RootWindow;
|
var rootWindow = tab?.RootWindow;
|
||||||
@@ -339,6 +347,8 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
|
if (IsSingleFloatingWindow)
|
||||||
|
return base.OnMouseDown(location, button);
|
||||||
MouseDownWindow = GetTabAtPos(location, out IsMouseDownOverCross);
|
MouseDownWindow = GetTabAtPos(location, out IsMouseDownOverCross);
|
||||||
|
|
||||||
// Check buttons
|
// Check buttons
|
||||||
@@ -368,6 +378,9 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
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
|
// Check tabs under mouse position at the beginning and at the end
|
||||||
var tab = GetTabAtPos(location, out var overCross);
|
var tab = GetTabAtPos(location, out var overCross);
|
||||||
|
|
||||||
@@ -410,7 +423,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
public override void OnMouseMove(Float2 location)
|
public override void OnMouseMove(Float2 location)
|
||||||
{
|
{
|
||||||
MousePosition = location;
|
MousePosition = location;
|
||||||
if (IsMouseLeftButtonDown)
|
if (IsMouseLeftButtonDown && !IsSingleFloatingWindow)
|
||||||
{
|
{
|
||||||
// Check if mouse is outside the header
|
// Check if mouse is outside the header
|
||||||
if (!HeaderRectangle.Contains(location))
|
if (!HeaderRectangle.Contains(location))
|
||||||
@@ -501,7 +514,10 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void GetDesireClientArea(out Rectangle rect)
|
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)
|
private DragDropEffect TrySelectTabUnderLocation(ref Float2 location)
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.AllowMaximize = true;
|
settings.AllowMaximize = true;
|
||||||
settings.AllowDragAndDrop = true;
|
settings.AllowDragAndDrop = true;
|
||||||
settings.IsTopmost = false;
|
settings.IsTopmost = false;
|
||||||
settings.IsRegularWindow = true;
|
settings.Type = WindowType.Regular;
|
||||||
settings.HasSizingFrame = true;
|
settings.HasSizingFrame = true;
|
||||||
settings.ShowAfterFirstPaint = false;
|
settings.ShowAfterFirstPaint = false;
|
||||||
settings.ShowInTaskbar = true;
|
settings.ShowInTaskbar = true;
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Input
|
|||||||
base.Draw();
|
base.Draw();
|
||||||
|
|
||||||
var style = Style.Current;
|
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.FillRectangle(r, _value);
|
||||||
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
|
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
|
||||||
|
|||||||
@@ -132,6 +132,8 @@ namespace FlaxEditor.GUI.Input
|
|||||||
_isSliding = false;
|
_isSliding = false;
|
||||||
EndMouseCapture();
|
EndMouseCapture();
|
||||||
SlidingEnd?.Invoke();
|
SlidingEnd?.Invoke();
|
||||||
|
Defocus();
|
||||||
|
Parent?.Focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -183,6 +185,8 @@ namespace FlaxEditor.GUI.Input
|
|||||||
{
|
{
|
||||||
// Click change
|
// Click change
|
||||||
Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
|
Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
|
||||||
|
Defocus();
|
||||||
|
Parent?.Focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,6 +201,10 @@ namespace FlaxEditor.GUI.Input
|
|||||||
// Update sliding
|
// Update sliding
|
||||||
var slidePosition = location + Root.TrackingMouseOffset;
|
var slidePosition = location + Root.TrackingMouseOffset;
|
||||||
Value = Mathf.Remap(slidePosition.X, 4, TrackSize - 4, Minimum, Maximum);
|
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
|
else
|
||||||
{
|
{
|
||||||
@@ -364,7 +372,7 @@ namespace FlaxEditor.GUI.Input
|
|||||||
};
|
};
|
||||||
_slider.ValueChanged += SliderOnValueChanged;
|
_slider.ValueChanged += SliderOnValueChanged;
|
||||||
_slider.SlidingStart += SlidingStart;
|
_slider.SlidingStart += SlidingStart;
|
||||||
_slider.SlidingEnd += SlidingEnd;
|
_slider.SlidingEnd += SliderOnSliderEnd;
|
||||||
_textBox = new TextBox(false, split, 0)
|
_textBox = new TextBox(false, split, 0)
|
||||||
{
|
{
|
||||||
Text = _value.ToString(CultureInfo.InvariantCulture),
|
Text = _value.ToString(CultureInfo.InvariantCulture),
|
||||||
@@ -375,6 +383,13 @@ namespace FlaxEditor.GUI.Input
|
|||||||
_textBox.EditEnd += OnTextBoxEditEnd;
|
_textBox.EditEnd += OnTextBoxEditEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SliderOnSliderEnd()
|
||||||
|
{
|
||||||
|
SlidingEnd?.Invoke();
|
||||||
|
Defocus();
|
||||||
|
Parent?.Focus();
|
||||||
|
}
|
||||||
|
|
||||||
private void SliderOnValueChanged()
|
private void SliderOnValueChanged()
|
||||||
{
|
{
|
||||||
if (_valueIsChanging)
|
if (_valueIsChanging)
|
||||||
@@ -397,6 +412,8 @@ namespace FlaxEditor.GUI.Input
|
|||||||
{
|
{
|
||||||
UpdateText();
|
UpdateText();
|
||||||
}
|
}
|
||||||
|
Defocus();
|
||||||
|
Parent?.Focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ namespace FlaxEditor.GUI.Input
|
|||||||
return base.OnMouseDown(location, button);
|
return base.OnMouseDown(location, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !PLATFORM_SDL
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnMouseMove(Float2 location)
|
public override void OnMouseMove(Float2 location)
|
||||||
{
|
{
|
||||||
@@ -292,6 +293,36 @@ namespace FlaxEditor.GUI.Input
|
|||||||
base.OnMouseMove(location);
|
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 />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ namespace FlaxEditor.GUI
|
|||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
public class Item : Control
|
public class Item : Control
|
||||||
{
|
{
|
||||||
|
private bool _isStartsWithMatch;
|
||||||
|
private bool _isFullMatch;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The is mouse down flag.
|
/// The is mouse down flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -43,6 +46,11 @@ namespace FlaxEditor.GUI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string Category;
|
public string Category;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A computed score for the context menu order
|
||||||
|
/// </summary>
|
||||||
|
public float SortScore;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when items gets clicked by the user.
|
/// Occurs when items gets clicked by the user.
|
||||||
/// </summary>
|
/// </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>
|
/// <summary>
|
||||||
/// Updates the filter.
|
/// Updates the filter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filterText">The filter text.</param>
|
/// <param name="filterText">The filter text.</param>
|
||||||
public void UpdateFilter(string filterText)
|
public void UpdateFilter(string filterText)
|
||||||
{
|
{
|
||||||
|
_isStartsWithMatch = _isFullMatch = false;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(filterText))
|
if (string.IsNullOrWhiteSpace(filterText))
|
||||||
{
|
{
|
||||||
// Clear filter
|
// Clear filter
|
||||||
_highlights?.Clear();
|
_highlights?.Clear();
|
||||||
Visible = true;
|
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)
|
||||||
// Update highlights
|
_highlights = new List<Rectangle>(ranges.Length);
|
||||||
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;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
_highlights.Clear();
|
||||||
|
var style = Style.Current;
|
||||||
|
var font = style.FontSmall;
|
||||||
|
for (int i = 0; i < ranges.Length; i++)
|
||||||
{
|
{
|
||||||
// Hide
|
var start = font.GetCharPosition(Name, ranges[i].StartIndex);
|
||||||
_highlights?.Clear();
|
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
|
||||||
Visible = false;
|
_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>
|
/// <summary>
|
||||||
@@ -178,7 +211,14 @@ namespace FlaxEditor.GUI
|
|||||||
public override int Compare(Control other)
|
public override int Compare(Control other)
|
||||||
{
|
{
|
||||||
if (other is Item otherItem)
|
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);
|
return base.Compare(other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,7 +289,10 @@ namespace FlaxEditor.GUI
|
|||||||
for (int i = 0; i < items.Count; i++)
|
for (int i = 0; i < items.Count; i++)
|
||||||
{
|
{
|
||||||
if (items[i] is Item item)
|
if (items[i] is Item item)
|
||||||
|
{
|
||||||
item.UpdateFilter(_searchBox.Text);
|
item.UpdateFilter(_searchBox.Text);
|
||||||
|
item.UpdateScore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_categoryPanels != null)
|
if (_categoryPanels != null)
|
||||||
{
|
{
|
||||||
@@ -262,6 +305,7 @@ namespace FlaxEditor.GUI
|
|||||||
if (category.Children[j] is Item item2)
|
if (category.Children[j] is Item item2)
|
||||||
{
|
{
|
||||||
item2.UpdateFilter(_searchBox.Text);
|
item2.UpdateFilter(_searchBox.Text);
|
||||||
|
item2.UpdateScore();
|
||||||
anyVisible |= item2.Visible;
|
anyVisible |= item2.Visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -273,6 +317,8 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SortItems();
|
||||||
|
|
||||||
UnlockChildrenRecursive();
|
UnlockChildrenRecursive();
|
||||||
PerformLayout(true);
|
PerformLayout(true);
|
||||||
_searchBox.Focus();
|
_searchBox.Focus();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace FlaxEditor.GUI
|
|||||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||||
public sealed class MainMenu : ContainerControl
|
public sealed class MainMenu : ContainerControl
|
||||||
{
|
{
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
private bool _useCustomWindowSystem;
|
private bool _useCustomWindowSystem;
|
||||||
private Image _icon;
|
private Image _icon;
|
||||||
private Label _title;
|
private Label _title;
|
||||||
@@ -67,7 +67,7 @@ namespace FlaxEditor.GUI
|
|||||||
AutoFocus = false;
|
AutoFocus = false;
|
||||||
AnchorPreset = AnchorPresets.HorizontalStretchTop;
|
AnchorPreset = AnchorPresets.HorizontalStretchTop;
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
_useCustomWindowSystem = !Editor.Instance.Options.Options.Interface.UseNativeWindowSystem;
|
_useCustomWindowSystem = !Editor.Instance.Options.Options.Interface.UseNativeWindowSystem;
|
||||||
if (_useCustomWindowSystem)
|
if (_useCustomWindowSystem)
|
||||||
{
|
{
|
||||||
@@ -166,7 +166,7 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Update(float deltaTime)
|
public override void Update(float deltaTime)
|
||||||
{
|
{
|
||||||
@@ -291,7 +291,7 @@ namespace FlaxEditor.GUI
|
|||||||
if (base.OnMouseDoubleClick(location, button))
|
if (base.OnMouseDoubleClick(location, button))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
var child = GetChildAtRecursive(location);
|
var child = GetChildAtRecursive(location);
|
||||||
if (_useCustomWindowSystem && child is not Button && child is not MainMenuButton)
|
if (_useCustomWindowSystem && child is not Button && child is not MainMenuButton)
|
||||||
{
|
{
|
||||||
@@ -321,7 +321,7 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
if (_useCustomWindowSystem)
|
if (_useCustomWindowSystem)
|
||||||
{
|
{
|
||||||
// Icon
|
// Icon
|
||||||
@@ -349,7 +349,7 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
if (_useCustomWindowSystem)
|
if (_useCustomWindowSystem)
|
||||||
{
|
{
|
||||||
// Buttons
|
// Buttons
|
||||||
@@ -367,7 +367,7 @@ namespace FlaxEditor.GUI
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnDestroy()
|
public override void OnDestroy()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace FlaxEditor.GUI
|
|||||||
Text = text;
|
Text = text;
|
||||||
|
|
||||||
var style = Style.Current;
|
var style = Style.Current;
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
if (Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
|
if (Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
|
||||||
{
|
{
|
||||||
BackgroundColorMouseOver = style.BackgroundHighlighted;
|
BackgroundColorMouseOver = style.BackgroundHighlighted;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace FlaxEditor.GUI
|
|||||||
ContentItem = item;
|
ContentItem = item;
|
||||||
ContentItem.AddReference(this);
|
ContentItem.AddReference(this);
|
||||||
|
|
||||||
Name = item.ShortName;
|
OnItemRenamed(item);
|
||||||
TooltipText = item.Path;
|
TooltipText = item.Path;
|
||||||
|
|
||||||
Height = IconSize + 4;
|
Height = IconSize + 4;
|
||||||
@@ -82,7 +82,9 @@ namespace FlaxEditor.GUI
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void OnItemRenamed(ContentItem item)
|
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 />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -130,12 +130,14 @@ namespace FlaxEditor.GUI
|
|||||||
|
|
||||||
var style = Style.Current;
|
var style = Style.Current;
|
||||||
var font = column.TitleFont ?? style.FontMedium;
|
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)
|
if (columnIndex < _columns.Length - 1)
|
||||||
{
|
{
|
||||||
var splitRect = new Rectangle(rect.Right - 1, 2, 2, rect.Height - 4);
|
var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
|
||||||
Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : column.TitleBackgroundColor * 0.9f);
|
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);
|
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))
|
if (splitRect.Contains(location))
|
||||||
{
|
{
|
||||||
// Start moving splitter
|
// Start moving splitter
|
||||||
@@ -193,6 +195,31 @@ namespace FlaxEditor.GUI
|
|||||||
|
|
||||||
PerformLayout();
|
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);
|
base.OnMouseMove(location);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
/// The keyframes.
|
/// The keyframes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[EditorDisplay("Keyframes", EditorDisplayAttribute.InlineStyle), ExpandGroups]
|
[EditorDisplay("Keyframes", EditorDisplayAttribute.InlineStyle), ExpandGroups]
|
||||||
[Collection(CanReorderItems = false, ReadOnly = true)]
|
[Collection(CanReorderItems = false, CanResize = true)]
|
||||||
public List<KeyValuePair<string, object>> Keyframes;
|
public List<KeyValuePair<string, object>> Keyframes;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user