Compare commits
119 Commits
sdl3
...
woa_suppor
| Author | SHA1 | Date | |
|---|---|---|---|
| 74dcea373c | |||
| 70f8492c01 | |||
| 63acdccd43 | |||
| 03f74b0c50 | |||
| 0d21a3ba1b | |||
| d85a5bcd36 | |||
| 585ebceb6a | |||
| 593c82543f | |||
| 7f1bcd91f5 | |||
| 58214ffc35 | |||
| 67b4b01697 | |||
| bd880c0e2f | |||
| 0bca21a1d4 | |||
| c5e3d4afd3 | |||
| bb1bee40e4 | |||
| 1b0b8998f9 | |||
| e4764c4d84 | |||
| 2de756f761 | |||
| 83f40be4f5 | |||
| 87a73c9b73 | |||
| 7054f942f6 | |||
| 227eaff9e2 | |||
| 563a45633f | |||
| 09e0754902 | |||
| 3dfe0e6c5a | |||
| 9e7af72046 | |||
| 96eb8cb0ca | |||
| ff86057a0a | |||
| 56abd82c9b | |||
| 9777bef9df | |||
| 9fedacb404 | |||
| 84f7fde753 | |||
| a5566d297f | |||
| 3f299f99cd | |||
| 741fc959e6 | |||
| 93fd560723 | |||
| cf48ce6d93 | |||
| bdd3b754bd | |||
| 99c27c9c30 | |||
|
|
97be8ee8cc | ||
|
|
1d6e8c4b7c | ||
|
|
82bf4238df | ||
|
|
9d2dc91920 | ||
|
|
3ae30a59b3 | ||
|
|
a742ce1d32 | ||
|
|
3593f835cd | ||
|
|
df086f3b3b | ||
|
|
6b31d51e31 | ||
|
|
f0d143ecaa | ||
|
|
196aa020fd | ||
|
|
ffe5105602 | ||
|
|
4acaa62a07 | ||
|
|
e7508538e0 | ||
|
|
33202a74b0 | ||
|
|
571ba6773d | ||
|
|
40652a0ebc | ||
|
|
481a6de821 | ||
|
|
66b828ae92 | ||
|
|
b91f51fb46 | ||
|
|
e51d2dda00 | ||
|
|
a11fa46ee2 | ||
|
|
47f3ecbde2 | ||
|
|
deb2319190 | ||
|
|
4b8970f674 | ||
|
|
f43cd97907 | ||
|
|
5b2af6b3d5 | ||
|
|
f604503566 | ||
|
|
388a0f4196 | ||
|
|
754ed56119 | ||
|
|
dca8e391fa | ||
|
|
863794d3c0 | ||
|
|
0d8c9f6626 | ||
|
|
8a45dda98c | ||
|
|
0cdce9dba2 | ||
|
|
97078cda7e | ||
|
|
10c47b8c2a | ||
|
|
3ebf73ec22 | ||
|
|
ebe05d4a51 | ||
|
|
cdeb9a3b15 | ||
|
|
60e8d73079 | ||
|
|
cf23892bd4 | ||
|
|
25f3cef8c3 | ||
|
|
00f2a0b825 | ||
|
|
7342629a86 | ||
|
|
5f860db6a5 | ||
|
|
6233718b06 | ||
|
|
62444315de | ||
|
|
a532ea7b42 | ||
|
|
803249f126 | ||
|
|
4e65b76b8c | ||
|
|
890b2da108 | ||
|
|
eac1d19a09 | ||
|
|
c4949de28f | ||
|
|
340ef194d3 | ||
|
|
b4547ec4d2 | ||
|
|
89f7e442f7 | ||
|
|
e7bef5e880 | ||
|
|
ff7c986fb1 | ||
|
|
708fba5136 | ||
|
|
7d92779e99 | ||
|
|
4c8528dcae | ||
|
|
3efd1e4e84 | ||
|
|
0cc6669cbd | ||
|
|
8bd409e95d | ||
|
|
3d0d41ebff | ||
|
|
61323f8526 | ||
|
|
017def29d4 | ||
|
|
13a04c2941 | ||
|
|
bc9cdf5cdb | ||
|
|
f7470af42d | ||
|
|
5c356ec22a | ||
|
|
06a35da0a8 | ||
|
|
55af307c43 | ||
|
|
4ab572426d | ||
|
|
01d91bf102 | ||
|
|
2dfb1058b2 | ||
|
|
cdbb2cc813 | ||
|
|
0e00f1e0eb | ||
|
|
d13621e631 |
@@ -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
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -16,7 +16,6 @@
|
|||||||
#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;
|
||||||
@@ -26,9 +25,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__);
|
||||||
Texture2DArray DirectionalLightShadowMap : register(t__SRV__);
|
Buffer<float4> ShadowsBuffer : 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
|
||||||
@@ -80,11 +79,8 @@ 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;
|
||||||
if (DirectionalLight.CastShadows > 0)
|
ShadowSample shadow = SampleDirectionalLightShadow(DirectionalLight, ShadowsBuffer, ShadowMap, gBuffer);
|
||||||
{
|
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)
|
||||||
float4x4 WorldMatrix;
|
float4x3 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;
|
||||||
float4x4 WorldMatrixInverseTransposed;
|
float4x3 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) WorldMatrix;
|
#define GetInstanceTransform(input) ToMatrix4x4(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), WorldMatrix).xyz;
|
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 TransformParticleVector(float3 input)
|
float3 TransformParticleVector(float3 input)
|
||||||
{
|
{
|
||||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
return mul(float4(input, 0.0f), ToMatrix4x4(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 = WorldMatrix;
|
float4x4 world = ToMatrix4x4(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,11 +463,12 @@ 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));
|
||||||
@@ -506,7 +507,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;
|
||||||
@@ -520,12 +521,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
|
||||||
@@ -625,12 +626,13 @@ 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
|
||||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||||
|
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(WorldMatrix, tangentToLocal);
|
half3x3 tangentToWorld = CalcTangentToWorld(world, 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)
|
||||||
float4x4 WorldMatrix;
|
float4x3 WorldMatrix;
|
||||||
float4x4 PrevWorldMatrix;
|
float4x3 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 = WorldMatrix; output.Geometry.InstanceTransform1 = world[0].xyz; output.Geometry.InstanceTransform2 = world[1].xyz; output.Geometry.InstanceTransform3 = world[2].xyz;
|
#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;
|
||||||
#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), PrevWorldMatrix).xyz;
|
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), ToMatrix4x4(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 = WorldMatrix;
|
float4x4 world = ToMatrix4x4(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), PrevWorldMatrix).xyz;
|
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||||
#else
|
#else
|
||||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), PrevWorldMatrix).xyz;
|
output.Geometry.PrevWorldPosition = mul(float4(position, 1), ToMatrix4x4(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)
|
||||||
float4x4 WorldMatrix;
|
float4x3 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)WorldMatrix;
|
float3x3 localToWorld = (float3x3)ToMatrix4x4(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)WorldMatrix;
|
float3x3 localToWorld = (float3x3)ToMatrix4x4(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 WorldMatrix[3].xyz;
|
return ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the current object size
|
// Gets the current object size
|
||||||
@@ -365,7 +365,8 @@ 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
|
||||||
output.Geometry.WorldPosition = mul(float4(position, 1), WorldMatrix).xyz;
|
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
||||||
|
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);
|
||||||
@@ -389,7 +390,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;
|
||||||
float4x4 WorldMatrix;
|
float4x3 WorldMatrix;
|
||||||
float4x4 WorldMatrixInverseTransposed;
|
float4x3 WorldMatrixInverseTransposed;
|
||||||
float3 GridSize;
|
float3 GridSize;
|
||||||
float PerInstanceRandom;
|
float PerInstanceRandom;
|
||||||
float Dummy0;
|
float Dummy0;
|
||||||
@@ -49,7 +49,7 @@ struct MaterialInput
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GetInstanceTransform(input) WorldMatrix;
|
#define GetInstanceTransform(input) ToMatrix4x4(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), WorldMatrix).xyz;
|
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 TransformParticleVector(float3 input)
|
float3 TransformParticleVector(float3 input)
|
||||||
{
|
{
|
||||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
return mul(float4(input, 0.0f), ToMatrix4x4(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 = WorldMatrix[3].xyz;
|
materialInput.InstanceOrigin = ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||||
materialInput.InstanceParams = PerInstanceRandom;
|
materialInput.InstanceParams = PerInstanceRandom;
|
||||||
materialInput.SvPosition = clipPos;
|
materialInput.SvPosition = clipPos;
|
||||||
Material material = GetMaterialPS(materialInput);
|
Material material = GetMaterialPS(materialInput);
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Editor/Grid.flax
LFS
BIN
Content/Shaders/Editor/Grid.flax
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Lights.flax
LFS
BIN
Content/Shaders/Lights.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Quad.flax
LFS
BIN
Content/Shaders/Quad.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Shadows.flax
LFS
BIN
Content/Shaders/Shadows.flax
LFS
Binary file not shown.
Binary file not shown.
@@ -2,9 +2,9 @@
|
|||||||
"Name": "Flax",
|
"Name": "Flax",
|
||||||
"Version": {
|
"Version": {
|
||||||
"Major": 1,
|
"Major": 1,
|
||||||
"Minor": 8,
|
"Minor": 9,
|
||||||
"Revision": 2,
|
"Revision": 0,
|
||||||
"Build": 6512
|
"Build": 6601
|
||||||
},
|
},
|
||||||
"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,7 +13,6 @@
|
|||||||
"Configuration": {
|
"Configuration": {
|
||||||
"UseCSharp": true,
|
"UseCSharp": true,
|
||||||
"UseLargeWorlds": false,
|
"UseLargeWorlds": false,
|
||||||
"UseDotNet": true,
|
"UseDotNet": true
|
||||||
"UseSDL": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,6 @@
|
|||||||
<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,3 +1,5 @@
|
|||||||
|
// 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;
|
||||||
@@ -94,30 +96,8 @@ public class AssetPickerValidator : IContentItemOwner
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string SelectedPath
|
public string SelectedPath
|
||||||
{
|
{
|
||||||
get
|
get => Utilities.Utils.ToPathProject(_selectedItem?.Path ?? _selected?.Path);
|
||||||
{
|
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>
|
||||||
@@ -242,7 +222,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 assets types that this picker accepts.</param>
|
/// <param name="assetType">The asset types that this picker accepts.</param>
|
||||||
public AssetPickerValidator(ScriptType assetType)
|
public AssetPickerValidator(ScriptType assetType)
|
||||||
{
|
{
|
||||||
_type = assetType;
|
_type = assetType;
|
||||||
|
|||||||
@@ -61,8 +61,6 @@ 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;
|
||||||
@@ -85,9 +83,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. Bool is for cutting.
|
/// Called when user wants to paste the files/folders.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<string[], bool> OnPaste;
|
public event Action<string[]> OnPaste;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when user wants to duplicate the item(s).
|
/// Called when user wants to duplicate the item(s).
|
||||||
@@ -212,12 +210,6 @@ 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),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -470,7 +462,6 @@ namespace FlaxEditor.Content.GUI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Duplicate()
|
public void Duplicate()
|
||||||
{
|
{
|
||||||
UpdateContentItemCut(false);
|
|
||||||
OnDuplicate?.Invoke(_selection);
|
OnDuplicate?.Invoke(_selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -484,7 +475,6 @@ 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>
|
||||||
@@ -506,36 +496,7 @@ namespace FlaxEditor.Content.GUI
|
|||||||
if (files == null || files.Length == 0)
|
if (files == null || files.Length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OnPaste?.Invoke(files, _isCutting);
|
OnPaste?.Invoke(files);
|
||||||
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,11 +182,6 @@ 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;
|
||||||
@@ -752,12 +747,6 @@ 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 />
|
||||||
|
|||||||
28
Source/Editor/Content/Items/VideoItem.cs
Normal file
28
Source/Editor/Content/Items/VideoItem.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// 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,16 +100,12 @@ 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,9 +30,7 @@ namespace FlaxEditor.Content
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether [is virtual proxy].
|
/// Determines whether [is virtual proxy].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>
|
/// <returns><c>true</c> if [is virtual proxy]; otherwise, <c>false</c>.</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,6 +29,12 @@ 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,6 +39,16 @@ 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,6 +87,12 @@ 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,6 +20,12 @@ 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,18 +166,6 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -189,12 +177,6 @@ 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,6 +73,16 @@ 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)
|
||||||
{
|
{
|
||||||
|
|||||||
48
Source/Editor/Content/Proxy/VideoProxy.cs
Normal file
48
Source/Editor/Content/Proxy/VideoProxy.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
// 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,6 +134,12 @@ 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>
|
||||||
@@ -285,24 +291,22 @@ public:
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The total assets amount in the build.
|
/// The total assets amount in the build.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int32 TotalAssets;
|
int32 TotalAssets = 0;
|
||||||
|
|
||||||
/// <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;
|
int32 CookedAssets = 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The final output content size in MB.
|
/// The final output content size (in bytes).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
int32 ContentSizeMB;
|
uint64 ContentSize = 0;
|
||||||
|
|
||||||
/// <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>
|
||||||
@@ -328,6 +332,11 @@ 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,6 +148,8 @@ 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("");
|
||||||
}
|
}
|
||||||
@@ -202,13 +204,6 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -307,6 +302,10 @@ 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.");
|
||||||
}
|
}
|
||||||
@@ -393,6 +392,9 @@ 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:
|
||||||
@@ -554,7 +556,12 @@ void GameCooker::GetCurrentPlatform(PlatformType& platform, BuildPlatform& build
|
|||||||
switch (PLATFORM_TYPE)
|
switch (PLATFORM_TYPE)
|
||||||
{
|
{
|
||||||
case PlatformType::Windows:
|
case PlatformType::Windows:
|
||||||
buildPlatform = PLATFORM_64BITS ? BuildPlatform::Windows64 : BuildPlatform::Windows32;
|
if (PLATFORM_ARCH == ArchitectureType::x64)
|
||||||
|
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,9 +325,7 @@ 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,47 +10,26 @@
|
|||||||
#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
|
||||||
_assetsQueue.Clear();
|
Array<Guid> assetsQueue;
|
||||||
_assetsQueue.EnsureCapacity(1024);
|
assetsQueue.Clear();
|
||||||
|
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;
|
||||||
while (_assetsQueue.HasItems())
|
Array<Guid> references;
|
||||||
|
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()
|
||||||
@@ -69,14 +48,31 @@ bool CollectAssetsStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load asset
|
// Load asset
|
||||||
const auto asset = Content::LoadAsync<Asset>(assetId);
|
AssetReference<Asset> 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,15 +12,7 @@ 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,6 +447,7 @@ 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();
|
||||||
@@ -891,7 +892,6 @@ 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,7 +904,6 @@ 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>
|
||||||
@@ -933,7 +932,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint64 GetPackagesSizeTotal() const
|
uint64 GetPackagesSizeTotal() const
|
||||||
{
|
{
|
||||||
return packagesSizeTotal;
|
return packagesSizeTotal;
|
||||||
@@ -1042,8 +1040,11 @@ 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.9f;
|
float Step2ProgressEnd = 0.8f;
|
||||||
String Step2Info = TEXT("Packaging assets");
|
String Step2Info = TEXT("Cooking files");
|
||||||
|
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);
|
||||||
|
|
||||||
@@ -1100,11 +1101,14 @@ bool CookAssetsStep::Perform(CookingData& data)
|
|||||||
#endif
|
#endif
|
||||||
int32 subStepIndex = 0;
|
int32 subStepIndex = 0;
|
||||||
AssetReference<Asset> assetRef;
|
AssetReference<Asset> assetRef;
|
||||||
assetRef.Unload.Bind([]() { LOG(Error, "Asset gets unloaded while cooking it!"); Platform::Sleep(100); });
|
assetRef.Unload.Bind([]
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -1184,6 +1188,35 @@ 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;
|
||||||
@@ -1229,13 +1262,11 @@ 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);
|
||||||
@@ -1253,12 +1284,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.ContentSizeMB = static_cast<int32>(packageBuilder.GetPackagesSizeTotal() / (1024 * 1024));
|
data.Stats.ContentSize += packageBuilder.GetPackagesSizeTotal();
|
||||||
}
|
}
|
||||||
|
|
||||||
BUILD_STEP_CANCEL_CHECK;
|
BUILD_STEP_CANCEL_CHECK;
|
||||||
|
|
||||||
data.StepProgress(TEXT("Creating assets cache"), Step2ProgressEnd);
|
data.StepProgress(TEXT("Creating assets cache"), Step3ProgressEnd);
|
||||||
|
|
||||||
// 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.
|
||||||
@@ -1291,7 +1322,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(), data.Stats.ContentSizeMB);
|
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)));
|
||||||
{
|
{
|
||||||
Array<CookingData::AssetTypeStatistics> assetTypes;
|
Array<CookingData::AssetTypeStatistics> assetTypes;
|
||||||
data.Stats.AssetStats.GetValues(assetTypes);
|
data.Stats.AssetStats.GetValues(assetTypes);
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ 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:
|
||||||
@@ -159,7 +160,20 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed |= EditorUtilities::CopyDirectoryIfNewer(dstDotnet / TEXT("host/fxr") / version, srcDotnet / TEXT("host/fxr") / version, true);
|
// TODO: hostfxr for target platform should be copied from nuget package location: microsoft.netcore.app.runtime.<RID>/<VERSION>/runtimes/<RID>/native/hostfxr.dll
|
||||||
|
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,11 +111,6 @@ 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;
|
||||||
@@ -382,6 +377,10 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -664,7 +663,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((obj == null && !Values.Type.IsValueType) || Values.Type.IsInstanceOfType(obj))
|
if (obj == null || Values.Type.IsInstanceOfType(obj))
|
||||||
{
|
{
|
||||||
result = obj;
|
result = obj;
|
||||||
return true;
|
return true;
|
||||||
@@ -676,7 +675,20 @@ 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 => !string.IsNullOrEmpty(Clipboard.Text);
|
public bool CanPaste
|
||||||
|
{
|
||||||
|
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,35 +67,19 @@ 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);
|
||||||
|
|
||||||
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
|
// Add some UI
|
||||||
{
|
var panel = layout.CustomContainer<UniformGridPanel>();
|
||||||
// Add some UI
|
panel.CustomControl.Height = 20.0f;
|
||||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
panel.CustomControl.SlotsVertically = 1;
|
||||||
panel.CustomControl.Height = 20.0f;
|
panel.CustomControl.SlotsHorizontally = 2;
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Edit selected prefab asset
|
// Selecting actor prefab asset
|
||||||
var editPrefab = panel.Button("Edit Prefab");
|
var selectPrefab = panel.Button("Select Prefab");
|
||||||
editPrefab.Button.Clicked += () =>
|
selectPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Select(prefab);
|
||||||
{
|
|
||||||
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 string cachedPaintValue))
|
if (projectCache.TryGetCustomData("ClothGizmoPaintValue", out var cachedPaintValue))
|
||||||
_gizmoMode.PaintValue = JsonSerializer.Deserialize<float>(cachedPaintValue);
|
_gizmoMode.PaintValue = JsonSerializer.Deserialize<float>(cachedPaintValue);
|
||||||
if (projectCache.TryGetCustomData("ClothGizmoContinuousPaint", out string cachedContinuousPaint))
|
if (projectCache.TryGetCustomData("ClothGizmoContinuousPaint", out var cachedContinuousPaint))
|
||||||
_gizmoMode.ContinuousPaint = JsonSerializer.Deserialize<bool>(cachedContinuousPaint);
|
_gizmoMode.ContinuousPaint = JsonSerializer.Deserialize<bool>(cachedContinuousPaint);
|
||||||
if (projectCache.TryGetCustomData("ClothGizmoBrushFalloff", out string cachedBrushFalloff))
|
if (projectCache.TryGetCustomData("ClothGizmoBrushFalloff", out var cachedBrushFalloff))
|
||||||
_gizmoMode.BrushFalloff = JsonSerializer.Deserialize<float>(cachedBrushFalloff);
|
_gizmoMode.BrushFalloff = JsonSerializer.Deserialize<float>(cachedBrushFalloff);
|
||||||
if (projectCache.TryGetCustomData("ClothGizmoBrushSize", out string cachedBrushSize))
|
if (projectCache.TryGetCustomData("ClothGizmoBrushSize", out var cachedBrushSize))
|
||||||
_gizmoMode.BrushSize = JsonSerializer.Deserialize<float>(cachedBrushSize);
|
_gizmoMode.BrushSize = JsonSerializer.Deserialize<float>(cachedBrushSize);
|
||||||
if (projectCache.TryGetCustomData("ClothGizmoBrushStrength", out string cachedBrushStrength))
|
if (projectCache.TryGetCustomData("ClothGizmoBrushStrength", out var cachedBrushStrength))
|
||||||
_gizmoMode.BrushStrength = JsonSerializer.Deserialize<float>(cachedBrushStrength);
|
_gizmoMode.BrushStrength = JsonSerializer.Deserialize<float>(cachedBrushStrength);
|
||||||
|
|
||||||
gizmos.AddMode(_gizmoMode);
|
gizmos.AddMode(_gizmoMode);
|
||||||
|
|||||||
@@ -880,13 +880,6 @@ 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,13 +41,6 @@ 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;
|
||||||
@@ -73,13 +66,6 @@ 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;
|
||||||
@@ -136,13 +122,6 @@ 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,6 +6,7 @@ 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
|
||||||
@@ -50,7 +51,6 @@ 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,37 +58,8 @@ 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;
|
||||||
}
|
}
|
||||||
@@ -115,6 +86,37 @@ 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()
|
||||||
{
|
{
|
||||||
@@ -140,4 +142,155 @@ 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,9 +38,6 @@ 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>
|
||||||
@@ -53,12 +50,6 @@ 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)
|
||||||
@@ -80,107 +71,6 @@ 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);
|
||||||
@@ -216,9 +106,6 @@ 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;
|
||||||
@@ -236,92 +123,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
MouseButtonRightClicked += OnMouseButtonRightClicked;
|
MouseButtonRightClicked += OnMouseButtonRightClicked;
|
||||||
if (_canReorder)
|
if (_canReorder)
|
||||||
{
|
{
|
||||||
HeaderTextMargin = new Margin(18, 0, 0, 0);
|
// TODO: Drag drop
|
||||||
_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)
|
||||||
@@ -422,7 +227,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.CanResize;
|
_canResize = !collection.ReadOnly;
|
||||||
_readOnly = collection.ReadOnly;
|
_readOnly = collection.ReadOnly;
|
||||||
_minCount = collection.MinCount;
|
_minCount = collection.MinCount;
|
||||||
_maxCount = collection.MaxCount;
|
_maxCount = collection.MaxCount;
|
||||||
@@ -519,6 +324,7 @@ 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
|
||||||
@@ -634,39 +440,6 @@ 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,7 +189,6 @@ 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, Type != null ? $"None ({Utilities.Utils.GetPropertyNameUI(Type.ToString())})" : "-", nameRect, isEnabled ? Color.OrangeRed : Color.DarkOrange, TextAlignment.Near, TextAlignment.Center);
|
Render2D.DrawText(style.FontMedium, "-", nameRect, isEnabled ? Color.OrangeRed : Color.DarkOrange, TextAlignment.Near, TextAlignment.Center);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw picker button
|
// Draw picker button
|
||||||
|
|||||||
@@ -474,7 +474,32 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
}
|
}
|
||||||
if (layout.Editors.Count != 0)
|
if (layout.Editors.Count != 0)
|
||||||
{
|
{
|
||||||
return !string.IsNullOrEmpty(Clipboard.Text);
|
var sb = 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,6 +25,7 @@ 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,22 +83,6 @@ 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>"));
|
||||||
}
|
}
|
||||||
@@ -354,7 +338,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
protected abstract ulong GetValue(object value);
|
protected abstract ulong GetValue(object value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the value from long.
|
/// Gets 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.FromRGB(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled;
|
var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGBA(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,9 +318,7 @@ 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.FromRGB(header.Color);
|
element.Label.TextColor = Color.FromRGBA(header.Color);
|
||||||
var size = element.Label.Font.GetFont().MeasureText(header.Text);
|
|
||||||
element.Label.Height = size.Y;
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,11 @@ 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>
|
||||||
@@ -160,6 +165,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
{
|
{
|
||||||
Info = info;
|
Info = info;
|
||||||
Type = Info.ValueType;
|
Type = Info.ValueType;
|
||||||
|
IsObsolete = Info.HasAttribute(typeof(ObsoleteAttribute), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -247,11 +247,6 @@ 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;
|
||||||
@@ -335,7 +330,7 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
case GeneralOptions.StartupSceneModes.LastOpened:
|
case GeneralOptions.StartupSceneModes.LastOpened:
|
||||||
{
|
{
|
||||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
|
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName))
|
||||||
{
|
{
|
||||||
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
||||||
foreach (var scene in lastScenes)
|
foreach (var scene in lastScenes)
|
||||||
@@ -447,7 +442,7 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
case GeneralOptions.StartupSceneModes.LastOpened:
|
case GeneralOptions.StartupSceneModes.LastOpened:
|
||||||
{
|
{
|
||||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
|
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName))
|
||||||
{
|
{
|
||||||
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
||||||
foreach (var sceneId in lastScenes)
|
foreach (var sceneId in lastScenes)
|
||||||
@@ -464,7 +459,7 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore view
|
// Restore view
|
||||||
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out string lastSceneSpawnName))
|
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out var lastSceneSpawnName))
|
||||||
Windows.EditWin.Viewport.ViewRay = JsonSerializer.Deserialize<Ray>(lastSceneSpawnName);
|
Windows.EditWin.Viewport.ViewRay = JsonSerializer.Deserialize<Ray>(lastSceneSpawnName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -490,8 +485,6 @@ 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++)
|
||||||
@@ -1371,7 +1364,6 @@ 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,10 +5,8 @@ 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
|
||||||
{
|
{
|
||||||
@@ -105,9 +103,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 + 2, ButtonsSize, ButtonsSize);
|
private Rectangle Button2Rect => new Rectangle(Height + ButtonsOffset, ButtonsSize, ButtonsSize, ButtonsSize);
|
||||||
|
|
||||||
private Rectangle Button3Rect => new Rectangle(Height + ButtonsOffset, (ButtonsSize + 2) * 2, ButtonsSize, ButtonsSize);
|
private Rectangle Button3Rect => new Rectangle(Height + ButtonsOffset, ButtonsSize * 2, ButtonsSize, ButtonsSize);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
@@ -149,13 +147,6 @@ 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)
|
||||||
@@ -178,13 +169,6 @@ 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
|
||||||
@@ -192,24 +176,6 @@ 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,7 +1,6 @@
|
|||||||
// 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
|
||||||
{
|
{
|
||||||
@@ -44,20 +43,10 @@ namespace FlaxEditor.GUI
|
|||||||
public Color TitleColor = Color.White;
|
public Color TitleColor = Color.White;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The column title background color.
|
/// The column title background background.
|
||||||
/// </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,10 +1,7 @@
|
|||||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
#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;
|
||||||
@@ -114,7 +111,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the empty menu popup on a screen.
|
/// Shows the empty menu popup o na 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>
|
||||||
@@ -218,7 +215,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
desc.AllowMaximize = false;
|
desc.AllowMaximize = false;
|
||||||
desc.AllowDragAndDrop = false;
|
desc.AllowDragAndDrop = false;
|
||||||
desc.IsTopmost = true;
|
desc.IsTopmost = true;
|
||||||
desc.Type = WindowType.Utility;
|
desc.IsRegularWindow = false;
|
||||||
desc.HasSizingFrame = false;
|
desc.HasSizingFrame = false;
|
||||||
OnWindowCreating(ref desc);
|
OnWindowCreating(ref desc);
|
||||||
_window = Platform.CreateWindow(ref desc);
|
_window = Platform.CreateWindow(ref desc);
|
||||||
@@ -231,6 +228,8 @@ 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;
|
||||||
@@ -379,11 +378,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_SDL_WORKAROUNDS
|
|
||||||
private void OnWindowGotFocus()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
private void OnWindowGotFocus()
|
private void OnWindowGotFocus()
|
||||||
{
|
{
|
||||||
var child = _childCM;
|
var child = _childCM;
|
||||||
@@ -397,7 +391,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
private void OnWindowLostFocus()
|
private void OnWindowLostFocus()
|
||||||
{
|
{
|
||||||
@@ -496,12 +489,7 @@ 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,7 +40,6 @@ 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;
|
||||||
|
|
||||||
@@ -120,8 +119,10 @@ 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 string savedColors))
|
if (Editor.Instance.ProjectCache.TryGetCustomData("ColorPickerSavedColors", out var 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)
|
||||||
@@ -381,7 +382,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);
|
||||||
@@ -396,7 +397,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 += OnWindowLostFocus;
|
((WindowRootControl)Root).Window.LostFocus += OnCancel;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
base.OnShow();
|
base.OnShow();
|
||||||
@@ -505,7 +506,7 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
BackgroundColorHighlighted = savedColor,
|
BackgroundColorHighlighted = savedColor,
|
||||||
BackgroundColorSelected = savedColor.RGBMultiplied(0.8f),
|
BackgroundColorSelected = savedColor.RGBMultiplied(0.8f),
|
||||||
};
|
};
|
||||||
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
|
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||||
_savedColorButtons.Add(savedColorButton);
|
_savedColorButtons.Add(savedColorButton);
|
||||||
}
|
}
|
||||||
if (_savedColors.Count < 8)
|
if (_savedColors.Count < 8)
|
||||||
@@ -517,24 +518,11 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
TooltipText = "Save Color.",
|
TooltipText = "Save Color.",
|
||||||
Tag = null,
|
Tag = null,
|
||||||
};
|
};
|
||||||
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
|
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||||
_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()
|
||||||
{
|
{
|
||||||
@@ -559,9 +547,8 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
_disableEvents = true;
|
_disableEvents = true;
|
||||||
|
|
||||||
// Restore color if modified
|
// Restore color if modified
|
||||||
if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent)
|
if (_useDynamicEditing && _initialValue != _value)
|
||||||
{
|
{
|
||||||
_canPassLastChangeEvent = false;
|
|
||||||
_onChanged?.Invoke(_initialValue, false);
|
_onChanged?.Invoke(_initialValue, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,9 @@ 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();
|
||||||
@@ -75,16 +77,13 @@ 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>
|
||||||
@@ -102,8 +101,6 @@ 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();
|
||||||
@@ -441,7 +438,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.AllowMinimize = false;
|
settings.AllowMinimize = false;
|
||||||
settings.HasBorder = false;
|
settings.HasBorder = false;
|
||||||
settings.HasSizingFrame = false;
|
settings.HasSizingFrame = false;
|
||||||
settings.Type = WindowType.Utility;
|
settings.IsRegularWindow = false;
|
||||||
settings.SupportsTransparency = true;
|
settings.SupportsTransparency = true;
|
||||||
settings.ShowInTaskbar = false;
|
settings.ShowInTaskbar = false;
|
||||||
settings.ShowAfterFirstPaint = false;
|
settings.ShowAfterFirstPaint = false;
|
||||||
@@ -473,7 +470,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.AllowMinimize = false;
|
settings.AllowMinimize = false;
|
||||||
settings.HasBorder = false;
|
settings.HasBorder = false;
|
||||||
settings.HasSizingFrame = false;
|
settings.HasSizingFrame = false;
|
||||||
settings.Type = WindowType.Utility;
|
settings.IsRegularWindow = false;
|
||||||
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 - 1)
|
if (index < _tabs.Count - 2)
|
||||||
{
|
{
|
||||||
var tab = _tabs[index];
|
var tab = _tabs[index];
|
||||||
_tabs.RemoveAt(index);
|
_tabs.RemoveAt(index);
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ 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.
|
||||||
@@ -188,10 +187,6 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -326,9 +321,6 @@ 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;
|
||||||
@@ -347,8 +339,6 @@ 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
|
||||||
@@ -378,9 +368,6 @@ 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);
|
||||||
|
|
||||||
@@ -423,7 +410,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
public override void OnMouseMove(Float2 location)
|
public override void OnMouseMove(Float2 location)
|
||||||
{
|
{
|
||||||
MousePosition = location;
|
MousePosition = location;
|
||||||
if (IsMouseLeftButtonDown && !IsSingleFloatingWindow)
|
if (IsMouseLeftButtonDown)
|
||||||
{
|
{
|
||||||
// Check if mouse is outside the header
|
// Check if mouse is outside the header
|
||||||
if (!HeaderRectangle.Contains(location))
|
if (!HeaderRectangle.Contains(location))
|
||||||
@@ -514,10 +501,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void GetDesireClientArea(out Rectangle rect)
|
public override void GetDesireClientArea(out Rectangle rect)
|
||||||
{
|
{
|
||||||
if (IsSingleFloatingWindow)
|
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
|
||||||
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.Type = WindowType.Regular;
|
settings.IsRegularWindow = true;
|
||||||
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(0, 0, Width, Height);
|
var r = new Rectangle(2, 2, Width - 4, Height - 4);
|
||||||
|
|
||||||
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,8 +132,6 @@ namespace FlaxEditor.GUI.Input
|
|||||||
_isSliding = false;
|
_isSliding = false;
|
||||||
EndMouseCapture();
|
EndMouseCapture();
|
||||||
SlidingEnd?.Invoke();
|
SlidingEnd?.Invoke();
|
||||||
Defocus();
|
|
||||||
Parent?.Focus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -185,8 +183,6 @@ namespace FlaxEditor.GUI.Input
|
|||||||
{
|
{
|
||||||
// Click change
|
// Click change
|
||||||
Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
|
Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
|
||||||
Defocus();
|
|
||||||
Parent?.Focus();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,10 +197,6 @@ 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
|
||||||
{
|
{
|
||||||
@@ -372,7 +364,7 @@ namespace FlaxEditor.GUI.Input
|
|||||||
};
|
};
|
||||||
_slider.ValueChanged += SliderOnValueChanged;
|
_slider.ValueChanged += SliderOnValueChanged;
|
||||||
_slider.SlidingStart += SlidingStart;
|
_slider.SlidingStart += SlidingStart;
|
||||||
_slider.SlidingEnd += SliderOnSliderEnd;
|
_slider.SlidingEnd += SlidingEnd;
|
||||||
_textBox = new TextBox(false, split, 0)
|
_textBox = new TextBox(false, split, 0)
|
||||||
{
|
{
|
||||||
Text = _value.ToString(CultureInfo.InvariantCulture),
|
Text = _value.ToString(CultureInfo.InvariantCulture),
|
||||||
@@ -383,13 +375,6 @@ 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)
|
||||||
@@ -412,8 +397,6 @@ namespace FlaxEditor.GUI.Input
|
|||||||
{
|
{
|
||||||
UpdateText();
|
UpdateText();
|
||||||
}
|
}
|
||||||
Defocus();
|
|
||||||
Parent?.Focus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -266,7 +266,6 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -293,36 +292,6 @@ 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,9 +23,6 @@ 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>
|
||||||
@@ -46,11 +43,6 @@ 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>
|
||||||
@@ -69,69 +61,44 @@ 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))
|
|
||||||
{
|
{
|
||||||
// Update highlights
|
if (QueryFilterHelper.Match(filterText, Name, out var ranges))
|
||||||
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);
|
// Update highlights
|
||||||
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
|
if (_highlights == null)
|
||||||
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
|
_highlights = new List<Rectangle>(ranges.Length);
|
||||||
|
else
|
||||||
if (ranges[i].StartIndex <= 0)
|
_highlights.Clear();
|
||||||
|
var style = Style.Current;
|
||||||
|
var font = style.FontSmall;
|
||||||
|
for (int i = 0; i < ranges.Length; i++)
|
||||||
{
|
{
|
||||||
_isStartsWithMatch = true;
|
var start = font.GetCharPosition(Name, ranges[i].StartIndex);
|
||||||
if (ranges[i].Length == Name.Length)
|
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
|
||||||
_isFullMatch = true;
|
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
|
||||||
}
|
}
|
||||||
|
Visible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hide
|
||||||
|
_highlights?.Clear();
|
||||||
|
Visible = false;
|
||||||
}
|
}
|
||||||
Visible = true;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide
|
|
||||||
_highlights?.Clear();
|
|
||||||
Visible = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -211,14 +178,7 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,10 +249,7 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -305,7 +262,6 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -317,8 +273,6 @@ 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 || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
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 || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
_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 || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
/// <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 || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
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 || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
if (_useCustomWindowSystem)
|
if (_useCustomWindowSystem)
|
||||||
{
|
{
|
||||||
// Icon
|
// Icon
|
||||||
@@ -349,7 +349,7 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
if (_useCustomWindowSystem)
|
if (_useCustomWindowSystem)
|
||||||
{
|
{
|
||||||
// Buttons
|
// Buttons
|
||||||
@@ -367,7 +367,7 @@ namespace FlaxEditor.GUI
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
/// <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 || PLATFORM_SDL
|
#if PLATFORM_WINDOWS
|
||||||
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);
|
||||||
|
|
||||||
OnItemRenamed(item);
|
Name = item.ShortName;
|
||||||
TooltipText = item.Path;
|
TooltipText = item.Path;
|
||||||
|
|
||||||
Height = IconSize + 4;
|
Height = IconSize + 4;
|
||||||
@@ -82,9 +82,7 @@ namespace FlaxEditor.GUI
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void OnItemRenamed(ContentItem item)
|
public void OnItemRenamed(ContentItem item)
|
||||||
{
|
{
|
||||||
Name = item.ShortName;
|
Name = ContentItem.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,14 +130,12 @@ namespace FlaxEditor.GUI
|
|||||||
|
|
||||||
var style = Style.Current;
|
var style = Style.Current;
|
||||||
var font = column.TitleFont ?? style.FontMedium;
|
var font = column.TitleFont ?? style.FontMedium;
|
||||||
var textRect = rect;
|
Render2D.DrawText(font, column.Title, rect, column.TitleColor, TextAlignment.Center, TextAlignment.Center);
|
||||||
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 - 2, 2, 4, rect.Height - 4);
|
var splitRect = new Rectangle(rect.Right - 1, 2, 2, rect.Height - 4);
|
||||||
Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : style.Background * 0.9f);
|
Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : column.TitleBackgroundColor * 0.9f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +151,7 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
rect.Width = GetColumnWidth(i);
|
rect.Width = GetColumnWidth(i);
|
||||||
|
|
||||||
var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
|
var splitRect = new Rectangle(rect.Right - 1, 2, 2, rect.Height - 4);
|
||||||
if (splitRect.Contains(location))
|
if (splitRect.Contains(location))
|
||||||
{
|
{
|
||||||
// Start moving splitter
|
// Start moving splitter
|
||||||
@@ -195,31 +193,6 @@ 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, CanResize = true)]
|
[Collection(CanReorderItems = false, ReadOnly = 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