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
|
||||
[lfs]
|
||||
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||
locksverify = false
|
||||
locksverify = false
|
||||
|
||||
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
@@ -16,7 +16,6 @@
|
||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||
@2// Forward Shading: Constants
|
||||
LightData DirectionalLight;
|
||||
LightShadowData DirectionalLightShadow;
|
||||
LightData SkyLight;
|
||||
ProbeData EnvironmentProbe;
|
||||
ExponentialHeightFogData ExponentialHeightFog;
|
||||
@@ -26,9 +25,9 @@ LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||
@3// Forward Shading: Resources
|
||||
TextureCube EnvProbe : 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
|
||||
DECLARE_LIGHTSHADOWDATA_ACCESS(DirectionalLightShadow);
|
||||
@5// Forward Shading: Shaders
|
||||
|
||||
// Pixel Shader function for Forward Pass
|
||||
@@ -80,11 +79,8 @@ void PS_Forward(
|
||||
|
||||
// Calculate lighting from a single directional light
|
||||
float4 shadowMask = 1.0f;
|
||||
if (DirectionalLight.CastShadows > 0)
|
||||
{
|
||||
LightShadowData directionalLightShadowData = GetDirectionalLightShadowData();
|
||||
shadowMask.r = SampleShadow(DirectionalLight, directionalLightShadowData, DirectionalLightShadowMap, gBuffer, shadowMask.g);
|
||||
}
|
||||
ShadowSample shadow = SampleDirectionalLightShadow(DirectionalLight, ShadowsBuffer, ShadowMap, gBuffer);
|
||||
shadowMask = GetShadowMask(shadow);
|
||||
float4 light = GetLighting(ViewPos, DirectionalLight, gBuffer, shadowMask, false, false);
|
||||
|
||||
// Calculate lighting from sky light
|
||||
|
||||
@@ -26,7 +26,7 @@ struct RibbonInput
|
||||
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
uint SortedIndicesOffset;
|
||||
float PerInstanceRandom;
|
||||
int ParticleStride;
|
||||
@@ -45,7 +45,7 @@ int RibbonWidthOffset;
|
||||
int RibbonTwistOffset;
|
||||
int RibbonFacingVectorOffset;
|
||||
uint RibbonSegmentCount;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
float4x3 WorldMatrixInverseTransposed;
|
||||
@1META_CB_END
|
||||
|
||||
// Particles attributes buffer
|
||||
@@ -138,7 +138,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
||||
#if USE_INSTANCING
|
||||
#define GetInstanceTransform(input) float4x4(float4(input.InstanceTransform1.xyz, 0.0f), float4(input.InstanceTransform2.xyz, 0.0f), float4(input.InstanceTransform3.xyz, 0.0f), float4(input.InstanceOrigin.xyz, 1.0f))
|
||||
#else
|
||||
#define GetInstanceTransform(input) WorldMatrix;
|
||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
||||
#endif
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
@@ -264,12 +264,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
|
||||
float3 TransformParticlePosition(float3 input)
|
||||
{
|
||||
return mul(float4(input, 1.0f), WorldMatrix).xyz;
|
||||
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
||||
}
|
||||
|
||||
@8
|
||||
@@ -333,7 +333,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
|
||||
float2 spriteSize = GetParticleVec2(particleIndex, SpriteSizeOffset);
|
||||
int spriteFacingMode = SpriteFacingModeOffset != -1 ? GetParticleInt(particleIndex, SpriteFacingModeOffset) : -1;
|
||||
|
||||
float4x4 world = WorldMatrix;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||
float3x3 viewRot = transpose((float3x3)ViewMatrix);
|
||||
float3 position = mul(float4(particlePosition, 1), world).xyz;
|
||||
@@ -463,11 +463,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
}
|
||||
|
||||
// Read particle data
|
||||
float4x4 worldMatrix = ToMatrix4x4(WorldMatrix);
|
||||
float3 particlePosition = GetParticleVec3(particleIndex, PositionOffset);
|
||||
float3 particleScale = GetParticleVec3(particleIndex, ScaleOffset);
|
||||
float3 particleRotation = GetParticleVec3(particleIndex, RotationOffset);
|
||||
int modelFacingMode = ModelFacingModeOffset != -1 ? GetParticleInt(particleIndex, ModelFacingModeOffset) : -1;
|
||||
float3 position = mul(float4(particlePosition, 1), WorldMatrix).xyz;
|
||||
float3 position = mul(float4(particlePosition, 1), worldMatrix).xyz;
|
||||
|
||||
// Compute final vertex position in the world
|
||||
float3x3 eulerMatrix = EulerMatrix(radians(particleRotation));
|
||||
@@ -506,7 +507,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
world = mul(world, scaleMatrix);
|
||||
}
|
||||
world = transpose(world);
|
||||
world = mul(world, WorldMatrix);
|
||||
world = mul(world, worldMatrix);
|
||||
|
||||
// Calculate the vertex position in world space
|
||||
output.WorldPosition = mul(float4(input.Position, 1), world).xyz;
|
||||
@@ -520,12 +521,12 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = input.Color;
|
||||
#endif
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
output.InstanceOrigin = worldMatrix[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = CalcTangentToLocal(input);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
||||
output.TBN = tangentToWorld;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
@@ -625,12 +626,13 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
|
||||
#if USE_VERTEX_COLOR
|
||||
output.VertexColor = 1;
|
||||
#endif
|
||||
output.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
output.InstanceOrigin = world[3].xyz;
|
||||
output.InstanceParams = PerInstanceRandom;
|
||||
|
||||
// Calculate tanget space to world space transformation matrix for unit vectors
|
||||
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
|
||||
output.TBN = tangentToWorld;
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 PrevWorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
float4x3 PrevWorldMatrix;
|
||||
float2 Dummy0;
|
||||
float LODDitherFactor;
|
||||
float PerInstanceRandom;
|
||||
@@ -171,7 +171,7 @@ MaterialInput GetMaterialInput(PixelInput input)
|
||||
#if USE_INSTANCING
|
||||
#define CalculateInstanceTransform(input) float4x4 world = GetInstanceTransform(input); output.Geometry.InstanceTransform1 = input.InstanceTransform1.xyz; output.Geometry.InstanceTransform2 = input.InstanceTransform2.xyz; output.Geometry.InstanceTransform3 = input.InstanceTransform3.xyz;
|
||||
#else
|
||||
#define CalculateInstanceTransform(input) float4x4 world = 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
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
@@ -328,7 +328,7 @@ VertexOutput VS(ModelInput input)
|
||||
// Compute world space vertex position
|
||||
CalculateInstanceTransform(input);
|
||||
output.Geometry.WorldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(input.Position.xyz, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
|
||||
// Compute clip space position
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -402,7 +402,7 @@ float4 VS_Depth(ModelInput_PosOnly input) : SV_Position
|
||||
#if USE_INSTANCING
|
||||
float4x4 world = GetInstanceTransform(input);
|
||||
#else
|
||||
float4x4 world = WorldMatrix;
|
||||
float4x4 world = ToMatrix4x4(WorldMatrix);
|
||||
#endif
|
||||
float3 worldPosition = mul(float4(input.Position.xyz, 1), world).xyz;
|
||||
float4 position = mul(float4(worldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -508,9 +508,9 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
|
||||
output.Geometry.WorldPosition = mul(float4(position, 1), world).xyz;
|
||||
#if PER_BONE_MOTION_BLUR
|
||||
float3 prevPosition = SkinPrevPosition(input);
|
||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(prevPosition, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
#else
|
||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), PrevWorldMatrix).xyz;
|
||||
output.Geometry.PrevWorldPosition = mul(float4(position, 1), ToMatrix4x4(PrevWorldMatrix)).xyz;
|
||||
#endif
|
||||
|
||||
// Compute clip space position
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
@7
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 WorldMatrix;
|
||||
float4x3 WorldMatrix;
|
||||
float3 WorldInvScale;
|
||||
float WorldDeterminantSign;
|
||||
float PerInstanceRandom;
|
||||
@@ -194,7 +194,7 @@ float3 TransformViewVectorToWorld(MaterialInput input, float3 viewVector)
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||
{
|
||||
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localVector, localToWorld);
|
||||
}
|
||||
@@ -202,7 +202,7 @@ float3 TransformLocalVectorToWorld(MaterialInput input, float3 localVector)
|
||||
// Transforms a vector from local space to world space
|
||||
float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
{
|
||||
float3x3 localToWorld = (float3x3)WorldMatrix;
|
||||
float3x3 localToWorld = (float3x3)ToMatrix4x4(WorldMatrix);
|
||||
//localToWorld = RemoveScaleFromLocalToWorld(localToWorld);
|
||||
return mul(localToWorld, worldVector);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ float3 TransformWorldVectorToLocal(MaterialInput input, float3 worldVector)
|
||||
// Gets the current object position
|
||||
float3 GetObjectPosition(MaterialInput input)
|
||||
{
|
||||
return WorldMatrix[3].xyz;
|
||||
return ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||
}
|
||||
|
||||
// Gets the current object size
|
||||
@@ -365,7 +365,8 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
float3 position = float3(positionXZ.x, height, positionXZ.y);
|
||||
|
||||
// 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
|
||||
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
|
||||
@@ -389,7 +390,7 @@ VertexOutput VS(TerrainVertexInput input)
|
||||
|
||||
// Compute world space normal vector
|
||||
float3x3 tangentToLocal = CalcTangentBasisFromWorldNormal(normal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(WorldMatrix, tangentToLocal);
|
||||
float3x3 tangentToWorld = CalcTangentToWorld(worldMatrix, tangentToLocal);
|
||||
output.Geometry.WorldNormal = tangentToWorld[2];
|
||||
|
||||
// Get material input params if need to evaluate any material property
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Primary constant buffer (with additional material parameters)
|
||||
META_CB_BEGIN(0, Data)
|
||||
float4x4 InverseViewProjectionMatrix;
|
||||
float4x4 WorldMatrix;
|
||||
float4x4 WorldMatrixInverseTransposed;
|
||||
float4x3 WorldMatrix;
|
||||
float4x3 WorldMatrixInverseTransposed;
|
||||
float3 GridSize;
|
||||
float PerInstanceRandom;
|
||||
float Dummy0;
|
||||
@@ -49,7 +49,7 @@ struct MaterialInput
|
||||
#endif
|
||||
};
|
||||
|
||||
#define GetInstanceTransform(input) WorldMatrix;
|
||||
#define GetInstanceTransform(input) ToMatrix4x4(WorldMatrix);
|
||||
|
||||
// Removes the scale vector from the local to world transformation matrix (supports instancing)
|
||||
float3x3 RemoveScaleFromLocalToWorld(float3x3 localToWorld)
|
||||
@@ -170,12 +170,12 @@ float4 GetParticleVec4(uint particleIndex, int offset)
|
||||
|
||||
float3 TransformParticlePosition(float3 input)
|
||||
{
|
||||
return mul(float4(input, 1.0f), WorldMatrix).xyz;
|
||||
return mul(float4(input, 1.0f), ToMatrix4x4(WorldMatrix)).xyz;
|
||||
}
|
||||
|
||||
float3 TransformParticleVector(float3 input)
|
||||
{
|
||||
return mul(float4(input, 0.0f), WorldMatrixInverseTransposed).xyz;
|
||||
return mul(float4(input, 0.0f), ToMatrix4x4(WorldMatrixInverseTransposed)).xyz;
|
||||
}
|
||||
|
||||
@8
|
||||
@@ -219,7 +219,7 @@ void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out fl
|
||||
materialInput.ParticleIndex = ParticleIndex;
|
||||
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
||||
materialInput.TwoSidedSign = 1.0f;
|
||||
materialInput.InstanceOrigin = WorldMatrix[3].xyz;
|
||||
materialInput.InstanceOrigin = ToMatrix4x4(WorldMatrix)[3].xyz;
|
||||
materialInput.InstanceParams = PerInstanceRandom;
|
||||
materialInput.SvPosition = clipPos;
|
||||
Material material = GetMaterialPS(materialInput);
|
||||
|
||||
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultRadialMenu.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultRadialMenu.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Editor/Grid.flax
(Stored with Git LFS)
BIN
Content/Shaders/Editor/Grid.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax
(Stored with Git LFS)
BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
BIN
Content/Shaders/GlobalSignDistanceField.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Lights.flax
(Stored with Git LFS)
BIN
Content/Shaders/Lights.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Quad.flax
(Stored with Git LFS)
BIN
Content/Shaders/Quad.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Shadows.flax
(Stored with Git LFS)
BIN
Content/Shaders/Shadows.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
BIN
Content/Shaders/VolumetricFog.flax
(Stored with Git LFS)
Binary file not shown.
@@ -2,9 +2,9 @@
|
||||
"Name": "Flax",
|
||||
"Version": {
|
||||
"Major": 1,
|
||||
"Minor": 8,
|
||||
"Revision": 2,
|
||||
"Build": 6512
|
||||
"Minor": 9,
|
||||
"Revision": 0,
|
||||
"Build": 6601
|
||||
},
|
||||
"Company": "Flax",
|
||||
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",
|
||||
@@ -13,7 +13,6 @@
|
||||
"Configuration": {
|
||||
"UseCSharp": true,
|
||||
"UseLargeWorlds": false,
|
||||
"UseDotNet": true,
|
||||
"UseSDL": true
|
||||
"UseDotNet": 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_005FMEMBER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ARGB/@EntryIndexedValue">ARGB</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LO/@EntryIndexedValue">LO</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RPC/@EntryIndexedValue">RPC</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SDK/@EntryIndexedValue">SDK</s:String>
|
||||
|
||||
@@ -14,8 +14,8 @@ call "Development\Scripts\Windows\CallBuildTool.bat" -genproject %*
|
||||
if errorlevel 1 goto BuildToolFailed
|
||||
|
||||
:: Build bindings for all editor configurations
|
||||
echo Building C# bindings...
|
||||
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
||||
::echo Building C# bindings...
|
||||
::Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
||||
|
||||
popd
|
||||
echo Done!
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using FlaxEditor.Scripting;
|
||||
@@ -94,30 +96,8 @@ public class AssetPickerValidator : IContentItemOwner
|
||||
/// </summary>
|
||||
public string SelectedPath
|
||||
{
|
||||
get
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
get => Utilities.Utils.ToPathProject(_selectedItem?.Path ?? _selected?.Path);
|
||||
set => SelectedItem = string.IsNullOrEmpty(value) ? null : Editor.Instance.ContentDatabase.Find(Utilities.Utils.ToPathAbsolute(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -242,7 +222,7 @@ public class AssetPickerValidator : IContentItemOwner
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AssetPickerValidator"/> class.
|
||||
/// </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)
|
||||
{
|
||||
_type = assetType;
|
||||
|
||||
@@ -61,8 +61,6 @@ namespace FlaxEditor.Content.GUI
|
||||
private bool _isRubberBandSpanning;
|
||||
private Float2 _mousePressLocation;
|
||||
private Rectangle _rubberBandRectangle;
|
||||
private bool _isCutting;
|
||||
private List<ContentItem> _cutItems = new List<ContentItem>();
|
||||
|
||||
private bool _validDragOver;
|
||||
private DragActors _dragActors;
|
||||
@@ -85,9 +83,9 @@ namespace FlaxEditor.Content.GUI
|
||||
public event Action<List<ContentItem>> OnDelete;
|
||||
|
||||
/// <summary>
|
||||
/// Called when user wants to paste the files/folders. Bool is for cutting.
|
||||
/// Called when user wants to paste the files/folders.
|
||||
/// </summary>
|
||||
public event Action<string[], bool> OnPaste;
|
||||
public event Action<string[]> OnPaste;
|
||||
|
||||
/// <summary>
|
||||
/// 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.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),
|
||||
});
|
||||
}
|
||||
@@ -470,7 +462,6 @@ namespace FlaxEditor.Content.GUI
|
||||
/// </summary>
|
||||
public void Duplicate()
|
||||
{
|
||||
UpdateContentItemCut(false);
|
||||
OnDuplicate?.Invoke(_selection);
|
||||
}
|
||||
|
||||
@@ -484,7 +475,6 @@ namespace FlaxEditor.Content.GUI
|
||||
|
||||
var files = _selection.ConvertAll(x => x.Path).ToArray();
|
||||
Clipboard.Files = files;
|
||||
UpdateContentItemCut(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -506,36 +496,7 @@ namespace FlaxEditor.Content.GUI
|
||||
if (files == null || files.Length == 0)
|
||||
return;
|
||||
|
||||
OnPaste?.Invoke(files, _isCutting);
|
||||
UpdateContentItemCut(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cuts the items.
|
||||
/// </summary>
|
||||
public void Cut()
|
||||
{
|
||||
Copy();
|
||||
UpdateContentItemCut(true);
|
||||
}
|
||||
|
||||
private void UpdateContentItemCut(bool cut)
|
||||
{
|
||||
_isCutting = cut;
|
||||
|
||||
// Add selection to cut list
|
||||
if (cut)
|
||||
_cutItems.AddRange(_selection);
|
||||
|
||||
// Update item with if it is being cut.
|
||||
foreach (var item in _cutItems)
|
||||
{
|
||||
item.IsBeingCut = cut;
|
||||
}
|
||||
|
||||
// Clean up cut items
|
||||
if (!cut)
|
||||
_cutItems.Clear();
|
||||
OnPaste?.Invoke(files);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -58,10 +58,10 @@ namespace FlaxEngine.Tools
|
||||
FieldInfo[] fields = typeof(CustomMaxSizes).GetFields();
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
var @field = fields[i];
|
||||
if (@field.Name.Equals("value__"))
|
||||
var field = fields[i];
|
||||
if (field.Name.Equals("value__"))
|
||||
continue;
|
||||
if (value == (int)@field.GetRawConstantValue())
|
||||
if (value == (int)field.GetRawConstantValue())
|
||||
return (CustomMaxSizes)value;
|
||||
}
|
||||
return CustomMaxSizes._8192;
|
||||
|
||||
@@ -182,11 +182,6 @@ namespace FlaxEditor.Content
|
||||
/// </summary>
|
||||
public const int DefaultHeight = (DefaultThumbnailSize + 2 * DefaultMarginSize + DefaultTextHeight);
|
||||
|
||||
/// <summary>
|
||||
/// Whether the item is being but.
|
||||
/// </summary>
|
||||
public bool IsBeingCut;
|
||||
|
||||
private ContentFolder _parentFolder;
|
||||
|
||||
private bool _isMouseDown;
|
||||
@@ -752,12 +747,6 @@ namespace FlaxEditor.Content
|
||||
Render2D.PushClip(ref textRect);
|
||||
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, 0.95f);
|
||||
Render2D.PopClip();
|
||||
|
||||
if (IsBeingCut)
|
||||
{
|
||||
var color = style.LightBackground.AlphaMultiplied(0.5f);
|
||||
Render2D.FillRectangle(clientRect, color);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
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 />
|
||||
public object GetValue(object obj)
|
||||
{
|
||||
if (!_type.Asset)
|
||||
throw new TargetException("Missing Visual Script asset.");
|
||||
return _type.Asset.GetScriptInstanceParameterValue(_parameter.Name, (Object)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetValue(object obj, object value)
|
||||
{
|
||||
if (!_type.Asset)
|
||||
throw new TargetException("Missing Visual Script asset.");
|
||||
_type.Asset.SetScriptInstanceParameterValue(_parameter.Name, (Object)obj, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,7 @@ namespace FlaxEditor.Content
|
||||
/// <summary>
|
||||
/// Determines whether [is virtual proxy].
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is virtual proxy]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <returns><c>true</c> if [is virtual proxy]; otherwise, <c>false</c>.</returns>
|
||||
public bool IsVirtualProxy()
|
||||
{
|
||||
return IsVirtual && CanExport == false;
|
||||
|
||||
@@ -29,6 +29,12 @@ namespace FlaxEditor.Content
|
||||
return item is CSharpScriptItem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ContentItem ConstructItem(string path)
|
||||
{
|
||||
return new CSharpScriptItem(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Create(string outputPath, object arg)
|
||||
{
|
||||
|
||||
@@ -39,6 +39,16 @@ namespace FlaxEditor.Content
|
||||
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>
|
||||
/// Gets a value indicating whether this proxy if for assets.
|
||||
/// </summary>
|
||||
|
||||
@@ -87,6 +87,12 @@ namespace FlaxEditor.Content
|
||||
return item is CppScriptItem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ContentItem ConstructItem(string path)
|
||||
{
|
||||
return new CppScriptItem(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void GetTemplatePaths(out string headerTemplate, out string sourceTemplate)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,12 @@ namespace FlaxEditor.Content
|
||||
return item is FileItem;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ContentItem ConstructItem(string path)
|
||||
{
|
||||
return new FileItem(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string FileExtension => string.Empty;
|
||||
|
||||
|
||||
@@ -166,18 +166,6 @@ namespace FlaxEditor.Content
|
||||
/// <inheritdoc />
|
||||
public override string Name { get; } = Utilities.Utils.GetPropertyNameUI(typeof(T).Name);
|
||||
|
||||
private SpriteHandle _thumbnail;
|
||||
|
||||
public SpawnableJsonAssetProxy()
|
||||
{
|
||||
_thumbnail = SpriteHandle.Invalid;
|
||||
}
|
||||
|
||||
public SpawnableJsonAssetProxy(SpriteHandle thumbnail)
|
||||
{
|
||||
_thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanCreate(ContentFolder targetLocation)
|
||||
{
|
||||
@@ -189,12 +177,6 @@ namespace FlaxEditor.Content
|
||||
{
|
||||
Editor.SaveJsonAsset(outputPath, new T());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
|
||||
{
|
||||
return _thumbnail.IsValid ? new JsonAssetItem(path, id, typeName, _thumbnail) : base.ConstructItem(path, typeName, ref id);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string TypeName { get; } = typeof(T).FullName;
|
||||
|
||||
@@ -73,6 +73,16 @@ namespace FlaxEditor.Content
|
||||
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 />
|
||||
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>
|
||||
API_ENUM(Attributes="EditorDisplay(null, \"iOS ARM64\")")
|
||||
iOSARM64 = 14,
|
||||
|
||||
/// <summary>
|
||||
/// Windows (ARM64)
|
||||
/// </summary>
|
||||
API_ENUM(Attributes = "EditorDisplay(null, \"Windows ARM64\")")
|
||||
WindowsARM64 = 15,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -285,24 +291,22 @@ public:
|
||||
/// <summary>
|
||||
/// The total assets amount in the build.
|
||||
/// </summary>
|
||||
int32 TotalAssets;
|
||||
int32 TotalAssets = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The cooked assets (TotalAssets - CookedAssets is amount of reused cached assets).
|
||||
/// </summary>
|
||||
int32 CookedAssets;
|
||||
int32 CookedAssets = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The final output content size in MB.
|
||||
/// The final output content size (in bytes).
|
||||
/// </summary>
|
||||
int32 ContentSizeMB;
|
||||
uint64 ContentSize = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The asset type stats. Key is the asset typename, value is the stats container.
|
||||
/// </summary>
|
||||
Dictionary<String, AssetTypeStatistics> AssetStats;
|
||||
|
||||
Statistics();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -328,6 +332,11 @@ public:
|
||||
/// </summary>
|
||||
HashSet<Guid> Assets;
|
||||
|
||||
/// <summary>
|
||||
/// The final files collection to include in build (valid only after CollectAssetsStep).
|
||||
/// </summary>
|
||||
HashSet<String> Files;
|
||||
|
||||
struct BinaryModuleInfo
|
||||
{
|
||||
String Name;
|
||||
|
||||
@@ -148,6 +148,8 @@ const Char* ToString(const BuildPlatform platform)
|
||||
return TEXT("Mac ARM64");
|
||||
case BuildPlatform::iOSARM64:
|
||||
return TEXT("iOS ARM64");
|
||||
case BuildPlatform::WindowsARM64:
|
||||
return TEXT("Windows ARM64");
|
||||
default:
|
||||
return TEXT("");
|
||||
}
|
||||
@@ -202,13 +204,6 @@ bool CookingData::AssetTypeStatistics::operator<(const AssetTypeStatistics& othe
|
||||
return Count > other.Count;
|
||||
}
|
||||
|
||||
CookingData::Statistics::Statistics()
|
||||
{
|
||||
TotalAssets = 0;
|
||||
CookedAssets = 0;
|
||||
ContentSizeMB = 0;
|
||||
}
|
||||
|
||||
CookingData::CookingData(const SpawnParams& params)
|
||||
: ScriptingObject(params)
|
||||
{
|
||||
@@ -307,6 +302,10 @@ void CookingData::GetBuildPlatformName(const Char*& platform, const Char*& archi
|
||||
platform = TEXT("iOS");
|
||||
architecture = TEXT("ARM64");
|
||||
break;
|
||||
case BuildPlatform::WindowsARM64:
|
||||
platform = TEXT("Windows");
|
||||
architecture = TEXT("ARM64");
|
||||
break;
|
||||
default:
|
||||
LOG(Fatal, "Unknown or unsupported build platform.");
|
||||
}
|
||||
@@ -393,6 +392,9 @@ PlatformTools* GameCooker::GetTools(BuildPlatform platform)
|
||||
case BuildPlatform::Windows64:
|
||||
result = New<WindowsPlatformTools>(ArchitectureType::x64);
|
||||
break;
|
||||
case BuildPlatform::WindowsARM64:
|
||||
result = New<WindowsPlatformTools>(ArchitectureType::ARM64);
|
||||
break;
|
||||
#endif
|
||||
#if PLATFORM_TOOLS_UWP
|
||||
case BuildPlatform::UWPx86:
|
||||
@@ -554,7 +556,12 @@ void GameCooker::GetCurrentPlatform(PlatformType& platform, BuildPlatform& build
|
||||
switch (PLATFORM_TYPE)
|
||||
{
|
||||
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;
|
||||
case PlatformType::XboxOne:
|
||||
buildPlatform = BuildPlatform::XboxOne;
|
||||
|
||||
@@ -325,9 +325,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
||||
|
||||
const auto buildSettings = BuildSettings::Get();
|
||||
if (buildSettings->SkipPackaging)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
GameCooker::PackageFiles();
|
||||
|
||||
// Validate environment variables
|
||||
|
||||
@@ -10,47 +10,26 @@
|
||||
#include "Engine/Content/Assets/Shader.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)
|
||||
{
|
||||
LOG(Info, "Searching for assets to include in a build. Using {0} root assets.", data.RootAssets.Count());
|
||||
data.StepProgress(TEXT("Collecting assets"), 0);
|
||||
|
||||
// Initialize assets queue
|
||||
_assetsQueue.Clear();
|
||||
_assetsQueue.EnsureCapacity(1024);
|
||||
Array<Guid> assetsQueue;
|
||||
assetsQueue.Clear();
|
||||
assetsQueue.EnsureCapacity(1024);
|
||||
for (auto i = data.RootAssets.Begin(); i.IsNotEnd(); ++i)
|
||||
_assetsQueue.Add(i->Item);
|
||||
assetsQueue.Add(i->Item);
|
||||
|
||||
// Iterate through the assets graph
|
||||
AssetInfo assetInfo;
|
||||
while (_assetsQueue.HasItems())
|
||||
Array<Guid> references;
|
||||
Array<String> files;
|
||||
while (assetsQueue.HasItems())
|
||||
{
|
||||
BUILD_STEP_CANCEL_CHECK;
|
||||
|
||||
const auto assetId = _assetsQueue.Dequeue();
|
||||
const Guid assetId = assetsQueue.Dequeue();
|
||||
|
||||
// Skip already processed or invalid assets
|
||||
if (!assetId.IsValid()
|
||||
@@ -69,14 +48,31 @@ bool CollectAssetsStep::Perform(CookingData& data)
|
||||
}
|
||||
|
||||
// Load asset
|
||||
const auto asset = Content::LoadAsync<Asset>(assetId);
|
||||
AssetReference<Asset> asset = Content::LoadAsync<Asset>(assetId);
|
||||
if (asset == nullptr)
|
||||
continue;
|
||||
|
||||
// Process that asset
|
||||
LOG_STR(Info, asset->GetPath());
|
||||
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();
|
||||
|
||||
@@ -12,15 +12,7 @@ class Asset;
|
||||
/// <seealso cref="GameCooker::BuildStep" />
|
||||
class CollectAssetsStep : public GameCooker::BuildStep
|
||||
{
|
||||
private:
|
||||
|
||||
Array<Guid> _assetsQueue;
|
||||
Array<Guid> _references;
|
||||
|
||||
bool Process(CookingData& data, Asset* asset);
|
||||
|
||||
public:
|
||||
|
||||
// [BuildStep]
|
||||
bool Perform(CookingData& data) override;
|
||||
};
|
||||
|
||||
@@ -447,6 +447,7 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
|
||||
#if PLATFORM_TOOLS_WINDOWS
|
||||
case BuildPlatform::Windows32:
|
||||
case BuildPlatform::Windows64:
|
||||
case BuildPlatform::WindowsARM64:
|
||||
{
|
||||
const char* platformDefineName = "PLATFORM_WINDOWS";
|
||||
const auto settings = WindowsPlatformSettings::Get();
|
||||
@@ -891,7 +892,6 @@ bool CookAssetsStep::Process(CookingData& data, CacheData& cache, JsonAssetBase*
|
||||
class PackageBuilder : public NonCopyable
|
||||
{
|
||||
private:
|
||||
|
||||
int32 _packageIndex;
|
||||
int32 MaxAssetsPerPackage;
|
||||
int32 MaxPackageSize;
|
||||
@@ -904,7 +904,6 @@ private:
|
||||
uint64 packagesSizeTotal;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PackageBuilder" /> class.
|
||||
/// </summary>
|
||||
@@ -933,7 +932,6 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
uint64 GetPackagesSizeTotal() const
|
||||
{
|
||||
return packagesSizeTotal;
|
||||
@@ -1042,8 +1040,11 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
float Step1ProgressEnd = 0.6f;
|
||||
String Step1Info = TEXT("Cooking assets");
|
||||
float Step2ProgressStart = Step1ProgressEnd;
|
||||
float Step2ProgressEnd = 0.9f;
|
||||
String Step2Info = TEXT("Packaging assets");
|
||||
float Step2ProgressEnd = 0.8f;
|
||||
String Step2Info = TEXT("Cooking files");
|
||||
float Step3ProgressStart = Step2ProgressStart;
|
||||
float Step3ProgressEnd = 0.9f;
|
||||
String Step3Info = TEXT("Packaging assets");
|
||||
|
||||
data.StepProgress(TEXT("Loading build cache"), 0);
|
||||
|
||||
@@ -1100,11 +1101,14 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
#endif
|
||||
int32 subStepIndex = 0;
|
||||
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)
|
||||
{
|
||||
BUILD_STEP_CANCEL_CHECK;
|
||||
|
||||
data.StepProgress(Step1Info, Math::Lerp(Step1ProgressStart, Step1ProgressEnd, static_cast<float>(subStepIndex++) / data.Assets.Count()));
|
||||
const Guid assetId = i->Item;
|
||||
|
||||
@@ -1184,6 +1188,35 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
// Save build cache header
|
||||
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
|
||||
{
|
||||
GameHeaderFlags gameFlags = GameHeaderFlags::None;
|
||||
@@ -1229,13 +1262,11 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
for (auto i = AssetsRegistry.Begin(); i.IsNotEnd(); ++i)
|
||||
{
|
||||
BUILD_STEP_CANCEL_CHECK;
|
||||
|
||||
data.StepProgress(Step2Info, Math::Lerp(Step2ProgressStart, Step2ProgressEnd, static_cast<float>(subStepIndex++) / AssetsRegistry.Count()));
|
||||
data.StepProgress(Step3Info, Math::Lerp(Step3ProgressStart, Step3ProgressEnd, (float)subStepIndex++ / AssetsRegistry.Count()));
|
||||
const auto assetId = i->Key;
|
||||
|
||||
String cookedFilePath;
|
||||
cache.GetFilePath(assetId, cookedFilePath);
|
||||
|
||||
if (!FileSystem::FileExists(cookedFilePath))
|
||||
{
|
||||
LOG(Warning, "Missing cooked file for asset \'{0}\'", assetId);
|
||||
@@ -1253,12 +1284,12 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
return true;
|
||||
for (auto& e : data.Stats.AssetStats)
|
||||
e.Value.TypeName = e.Key;
|
||||
data.Stats.ContentSizeMB = static_cast<int32>(packageBuilder.GetPackagesSizeTotal() / (1024 * 1024));
|
||||
data.Stats.ContentSize += packageBuilder.GetPackagesSizeTotal();
|
||||
}
|
||||
|
||||
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.
|
||||
// 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
|
||||
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;
|
||||
data.Stats.AssetStats.GetValues(assetTypes);
|
||||
|
||||
@@ -73,6 +73,7 @@ bool DeployDataStep::Perform(CookingData& data)
|
||||
{
|
||||
case BuildPlatform::Windows32:
|
||||
case BuildPlatform::Windows64:
|
||||
case BuildPlatform::WindowsARM64:
|
||||
canUseSystemDotnet = PLATFORM_TYPE == PlatformType::Windows;
|
||||
break;
|
||||
case BuildPlatform::LinuxX64:
|
||||
@@ -159,7 +160,20 @@ bool DeployDataStep::Perform(CookingData& data)
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (failed)
|
||||
|
||||
@@ -111,11 +111,6 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
public PropertyNameLabel LinkedLabel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the layout for this editor. Used to calculate bounds.
|
||||
/// </summary>
|
||||
public LayoutElementsContainer Layout => _layout;
|
||||
|
||||
internal virtual void Initialize(CustomEditorPresenter presenter, LayoutElementsContainer layout, ValueContainer values)
|
||||
{
|
||||
_layout = layout;
|
||||
@@ -382,6 +377,10 @@ namespace FlaxEditor.CustomEditors
|
||||
else if (Values.HasDefaultValue && CanRevertDefaultValue)
|
||||
color = Color.Yellow * 0.8f;
|
||||
LinkedLabel.HighlightStripColor = color;
|
||||
|
||||
// Grey out deprecated members
|
||||
if (Values.IsObsolete)
|
||||
LinkedLabel.TextColor = LinkedLabel.TextColorHighlighted = FlaxEngine.GUI.Style.Current.ForegroundGrey;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
return true;
|
||||
@@ -676,7 +675,20 @@ namespace FlaxEditor.CustomEditors
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether can paste value from the system clipboard to the property value container.
|
||||
/// </summary>
|
||||
public bool CanPaste => !string.IsNullOrEmpty(Clipboard.Text);
|
||||
public bool CanPaste
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetClipboardObject(out _, false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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
|
||||
Values.SetReferenceValue(prefabInstance);
|
||||
|
||||
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
|
||||
{
|
||||
// Add some UI
|
||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
||||
panel.CustomControl.Height = 20.0f;
|
||||
panel.CustomControl.SlotsVertically = 1;
|
||||
panel.CustomControl.SlotsHorizontally = 3;
|
||||
|
||||
// Selecting actor prefab asset
|
||||
var selectPrefab = panel.Button("Select Prefab");
|
||||
selectPrefab.Button.Clicked += () =>
|
||||
{
|
||||
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
|
||||
Editor.Instance.Windows.ContentWin.Select(prefab);
|
||||
};
|
||||
// Add some UI
|
||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
||||
panel.CustomControl.Height = 20.0f;
|
||||
panel.CustomControl.SlotsVertically = 1;
|
||||
panel.CustomControl.SlotsHorizontally = 2;
|
||||
|
||||
// Edit selected prefab asset
|
||||
var editPrefab = panel.Button("Edit Prefab");
|
||||
editPrefab.Button.Clicked += () =>
|
||||
{
|
||||
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
|
||||
Editor.Instance.Windows.ContentWin.Select(prefab);
|
||||
Editor.Instance.Windows.ContentWin.Open(Editor.Instance.Windows.ContentWin.View.Selection[0]);
|
||||
};
|
||||
// Selecting actor prefab asset
|
||||
var selectPrefab = panel.Button("Select Prefab");
|
||||
selectPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Select(prefab);
|
||||
|
||||
// Viewing changes applied to this actor
|
||||
var viewChanges = panel.Button("View Changes");
|
||||
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
||||
}
|
||||
// Viewing changes applied to this actor
|
||||
var viewChanges = panel.Button("View Changes");
|
||||
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
||||
|
||||
// Link event to update editor on prefab apply
|
||||
_linkedPrefabId = prefab.ID;
|
||||
|
||||
@@ -38,15 +38,15 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
_gizmoMode = new ClothPaintingGizmoMode();
|
||||
|
||||
var projectCache = Editor.Instance.ProjectCache;
|
||||
if (projectCache.TryGetCustomData("ClothGizmoPaintValue", out string cachedPaintValue))
|
||||
if (projectCache.TryGetCustomData("ClothGizmoPaintValue", out var 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);
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushFalloff", out string cachedBrushFalloff))
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushFalloff", out var 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);
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushStrength", out string cachedBrushStrength))
|
||||
if (projectCache.TryGetCustomData("ClothGizmoBrushStrength", out var cachedBrushStrength))
|
||||
_gizmoMode.BrushStrength = JsonSerializer.Deserialize<float>(cachedBrushStrength);
|
||||
|
||||
gizmos.AddMode(_gizmoMode);
|
||||
|
||||
@@ -880,13 +880,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
group.Panel.HeaderTextMargin = new Margin(scriptDrag.Right - 12, 15, 2, 2);
|
||||
group.Object(values, editor);
|
||||
// Remove drop down arrows and containment lines if no objects in the group
|
||||
if (group.Children.Count == 0)
|
||||
{
|
||||
group.Panel.ArrowImageOpened = null;
|
||||
group.Panel.ArrowImageClosed = null;
|
||||
group.Panel.EnableContainmentLines = false;
|
||||
}
|
||||
|
||||
// Scripts arrange bar
|
||||
dragBar = layout.Custom<ScriptArrangeBar>();
|
||||
|
||||
@@ -41,13 +41,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
base.Initialize(layout);
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
@@ -73,13 +66,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
base.Initialize(layout);
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
@@ -136,13 +122,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
menu.AddButton("Link", ToggleLink).LinkTooltip("Links scale components for uniform scaling");
|
||||
};
|
||||
}
|
||||
|
||||
if (XElement.ValueBox.Parent is UniformGridPanel ug)
|
||||
{
|
||||
ug.Height += 2;
|
||||
ug.SlotSpacing = new Float2(4);
|
||||
ug.SlotPadding = new Margin(0, 0, 1, 1);
|
||||
}
|
||||
|
||||
// Override colors
|
||||
var back = FlaxEngine.GUI.Style.Current.TextBoxBackground;
|
||||
|
||||
@@ -6,6 +6,7 @@ using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Utilities;
|
||||
|
||||
namespace FlaxEditor.CustomEditors.Editors
|
||||
@@ -50,7 +51,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (HasDifferentTypes)
|
||||
return;
|
||||
Picker = layout.Custom<AssetPicker>().CustomControl;
|
||||
|
||||
var value = Values[0];
|
||||
_valueType = Values.Type.Type != typeof(object) || value == null ? Values.Type : TypeUtils.GetObjectType(value);
|
||||
var assetType = _valueType;
|
||||
@@ -58,37 +58,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
assetType = new ScriptType(typeof(Asset));
|
||||
else if (_valueType.Type != null && _valueType.Type.Name == typeof(JsonAssetReference<>).Name)
|
||||
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;
|
||||
ApplyAssetReferenceAttribute(Values, out var height, Picker.Validator);
|
||||
Picker.Height = height;
|
||||
Picker.SelectedItemChanged += OnSelectedItemChanged;
|
||||
}
|
||||
@@ -115,6 +86,37 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
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 />
|
||||
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>
|
||||
public readonly int Index;
|
||||
|
||||
private Rectangle _arrangeButtonRect;
|
||||
private bool _arrangeButtonInUse;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CollectionItemLabel"/> class.
|
||||
/// </summary>
|
||||
@@ -53,12 +50,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Index = index;
|
||||
|
||||
SetupContextMenu += OnSetupContextMenu;
|
||||
_arrangeButtonRect = new Rectangle(2, 3, 12, 12);
|
||||
|
||||
// Extend margin of the label to support a dragging handle.
|
||||
Margin m = Margin;
|
||||
m.Left += 16;
|
||||
Margin = m;
|
||||
}
|
||||
|
||||
private void OnSetupContextMenu(PropertyNameLabel label, ContextMenu menu, CustomEditor linkedEditor)
|
||||
@@ -80,107 +71,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
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()
|
||||
{
|
||||
Editor.Move(Index, Index - 1);
|
||||
@@ -216,9 +106,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
private bool _canReorder = true;
|
||||
|
||||
private Rectangle _arrangeButtonRect;
|
||||
private bool _arrangeButtonInUse;
|
||||
|
||||
public void Setup(CollectionEditor editor, int index, bool canReorder = true)
|
||||
{
|
||||
HeaderHeight = 18;
|
||||
@@ -236,92 +123,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
MouseButtonRightClicked += OnMouseButtonRightClicked;
|
||||
if (_canReorder)
|
||||
{
|
||||
HeaderTextMargin = new Margin(18, 0, 0, 0);
|
||||
_arrangeButtonRect = new Rectangle(16, 3, 12, 12);
|
||||
// TODO: Drag drop
|
||||
}
|
||||
}
|
||||
|
||||
private bool ArrangeAreaCheck(out int index, out Rectangle rect)
|
||||
{
|
||||
var container = Parent;
|
||||
var mousePosition = container.PointFromScreen(Input.MouseScreenPosition);
|
||||
var barSidesExtend = 20.0f;
|
||||
var barHeight = 5.0f;
|
||||
var barCheckAreaHeight = 40.0f;
|
||||
var pos = mousePosition.Y + barCheckAreaHeight * 0.5f;
|
||||
|
||||
for (int i = 0; i < (container.Children.Count + 1) / 2; i++) // Add 1 to pretend there is a spacer at the end.
|
||||
{
|
||||
var containerChild = container.Children[i * 2]; // times 2 to skip the value editor
|
||||
if (Mathf.IsInRange(pos, containerChild.Top, containerChild.Top + barCheckAreaHeight) || (i == 0 && pos < containerChild.Top))
|
||||
{
|
||||
index = i;
|
||||
var p1 = containerChild.UpperLeft;
|
||||
rect = new Rectangle(PointFromParent(p1) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var p2 = container.Children[container.Children.Count - 1].BottomLeft;
|
||||
if (pos > p2.Y)
|
||||
{
|
||||
index = ((container.Children.Count + 1) / 2) - 1;
|
||||
rect = new Rectangle(PointFromParent(p2) - new Float2(barSidesExtend * 0.5f, barHeight * 0.5f), Width + barSidesExtend, barHeight);
|
||||
return true;
|
||||
}
|
||||
|
||||
index = -1;
|
||||
rect = Rectangle.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
base.Draw();
|
||||
if (_canReorder)
|
||||
{
|
||||
var style = FlaxEngine.GUI.Style.Current;
|
||||
|
||||
var mousePosition = PointFromScreen(Input.MouseScreenPosition);
|
||||
var dragBarColor = _arrangeButtonRect.Contains(mousePosition) ? style.Foreground : style.ForegroundGrey;
|
||||
Render2D.DrawSprite(FlaxEditor.Editor.Instance.Icons.DragBar12, _arrangeButtonRect, _arrangeButtonInUse ? Color.Orange : dragBarColor);
|
||||
if (_arrangeButtonInUse && ArrangeAreaCheck(out _, out var arrangeTargetRect))
|
||||
{
|
||||
Render2D.FillRectangle(arrangeTargetRect, style.Selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
|
||||
{
|
||||
_arrangeButtonInUse = true;
|
||||
Focus();
|
||||
StartMouseCapture();
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
if (button == MouseButton.Left && _arrangeButtonInUse)
|
||||
{
|
||||
_arrangeButtonInUse = false;
|
||||
EndMouseCapture();
|
||||
if (ArrangeAreaCheck(out var index, out _))
|
||||
{
|
||||
Editor.Shift(Index, index);
|
||||
}
|
||||
}
|
||||
|
||||
return base.OnMouseUp(location, button);
|
||||
}
|
||||
|
||||
private void OnMouseButtonRightClicked(DropPanel panel, Float2 location)
|
||||
{
|
||||
if (LinkedEditor == null)
|
||||
@@ -422,7 +227,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
||||
if (collection != null)
|
||||
{
|
||||
_canResize = collection.CanResize;
|
||||
_canResize = !collection.ReadOnly;
|
||||
_readOnly = collection.ReadOnly;
|
||||
_minCount = collection.MinCount;
|
||||
_maxCount = collection.MaxCount;
|
||||
@@ -519,6 +324,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
(elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) ||
|
||||
elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
|
||||
elementType.Equals(new ScriptType(typeof(SettingsBase)));
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
// Apply spacing
|
||||
@@ -634,39 +440,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
SetValue(cloned);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shifts the specified item at the given index and moves it through the list to the other item. It supports undo.
|
||||
/// </summary>
|
||||
/// <param name="srcIndex">Index of the source item.</param>
|
||||
/// <param name="dstIndex">Index of the destination to move to.</param>
|
||||
private void Shift(int srcIndex, int dstIndex)
|
||||
{
|
||||
if (IsSetBlocked)
|
||||
return;
|
||||
|
||||
var cloned = CloneValues();
|
||||
if (dstIndex > srcIndex)
|
||||
{
|
||||
for (int i = srcIndex; i < dstIndex; i++)
|
||||
{
|
||||
var tmp = cloned[i + 1];
|
||||
cloned[i + 1] = cloned[i];
|
||||
cloned[i] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = srcIndex; i > dstIndex; i--)
|
||||
{
|
||||
var tmp = cloned[i - 1];
|
||||
cloned[i - 1] = cloned[i];
|
||||
cloned[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
SetValue(cloned);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the item at the specified index. It supports undo.
|
||||
/// </summary>
|
||||
|
||||
@@ -189,7 +189,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
var collection = (CollectionAttribute)attributes?.FirstOrDefault(x => x is CollectionAttribute);
|
||||
if (collection != null)
|
||||
{
|
||||
_canEditKeys &= collection.CanReorderItems;
|
||||
_readOnly = collection.ReadOnly;
|
||||
_notNullItems = collection.NotNullItems;
|
||||
if (collection.BackgroundColor.HasValue)
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
else
|
||||
{
|
||||
// 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
|
||||
|
||||
@@ -474,7 +474,32 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
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))
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
new OptionType("Linear Gradient", typeof(LinearGradientBrush)),
|
||||
new OptionType("Texture 9-Slicing", typeof(Texture9SlicingBrush)),
|
||||
new OptionType("Sprite 9-Slicing", typeof(Sprite9SlicingBrush)),
|
||||
new OptionType("Video", typeof(VideoBrush)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,22 +83,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
_element.Value = asInt;
|
||||
else if (value is float asFloat)
|
||||
_element.Value = (int)asFloat;
|
||||
else if (value is double asDouble)
|
||||
_element.Value = (int)asDouble;
|
||||
else if (value is uint asUint)
|
||||
_element.Value = (int)asUint;
|
||||
else if (value is long asLong)
|
||||
_element.Value = (int)asLong;
|
||||
else if (value is ulong asULong)
|
||||
_element.Value = (int)asULong;
|
||||
else if (value is short asShort)
|
||||
_element.Value = asShort;
|
||||
else if (value is ushort asUshort)
|
||||
_element.Value = asUshort;
|
||||
else if (value is byte asByte)
|
||||
_element.Value = asByte;
|
||||
else if (value is sbyte asSbyte)
|
||||
_element.Value = asSbyte;
|
||||
else
|
||||
throw new Exception(string.Format("Invalid value type {0}.", value?.GetType().ToString() ?? "<null>"));
|
||||
}
|
||||
@@ -354,7 +338,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
protected abstract ulong GetValue(object value);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value from long.
|
||||
/// Gets the value from long.
|
||||
/// </summary>
|
||||
/// <param name="value">The value from editor.</param>
|
||||
/// <returns>The value to object.</returns>
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (watermarkAttribute is WatermarkAttribute watermark)
|
||||
{
|
||||
_watermarkText = watermark.WatermarkText;
|
||||
var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGB(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled;
|
||||
var watermarkColor = watermark.WatermarkColor > 0 ? Color.FromRGBA(watermark.WatermarkColor) : FlaxEngine.GUI.Style.Current.ForegroundDisabled;
|
||||
_watermarkColor = watermarkColor;
|
||||
_element.TextBox.WatermarkText = watermark.WatermarkText;
|
||||
_element.TextBox.WatermarkTextColor = watermarkColor;
|
||||
|
||||
@@ -318,9 +318,7 @@ namespace FlaxEditor.CustomEditors
|
||||
if (header.FontSize > 0)
|
||||
element.Label.Font = new FontReference(element.Label.Font.Font, header.FontSize);
|
||||
if (header.Color > 0)
|
||||
element.Label.TextColor = Color.FromRGB(header.Color);
|
||||
var size = element.Label.Font.GetFont().MeasureText(header.Text);
|
||||
element.Label.Height = size.Y;
|
||||
element.Label.TextColor = Color.FromRGBA(header.Color);
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,11 @@ namespace FlaxEditor.CustomEditors
|
||||
/// </summary>
|
||||
public bool IsArray => Type != ScriptType.Null && Type.IsArray;
|
||||
|
||||
/// <summary>
|
||||
/// True if member or type has <see cref="System.ObsoleteAttribute"/> that marks it as obsolete.
|
||||
/// </summary>
|
||||
public bool IsObsolete { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the values types array (without duplicates).
|
||||
/// </summary>
|
||||
@@ -160,6 +165,7 @@ namespace FlaxEditor.CustomEditors
|
||||
{
|
||||
Info = info;
|
||||
Type = Info.ValueType;
|
||||
IsObsolete = Info.HasAttribute(typeof(ObsoleteAttribute), true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -247,11 +247,6 @@ namespace FlaxEditor
|
||||
/// </summary>
|
||||
public event Action PlayModeEnd;
|
||||
|
||||
/// <summary>
|
||||
/// Fired on Editor update
|
||||
/// </summary>
|
||||
public event Action EditorUpdate;
|
||||
|
||||
internal Editor()
|
||||
{
|
||||
Instance = this;
|
||||
@@ -335,7 +330,7 @@ namespace FlaxEditor
|
||||
}
|
||||
case GeneralOptions.StartupSceneModes.LastOpened:
|
||||
{
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName))
|
||||
{
|
||||
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
||||
foreach (var scene in lastScenes)
|
||||
@@ -447,7 +442,7 @@ namespace FlaxEditor
|
||||
}
|
||||
case GeneralOptions.StartupSceneModes.LastOpened:
|
||||
{
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out string lastSceneIdName))
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastScene, out var lastSceneIdName))
|
||||
{
|
||||
var lastScenes = JsonSerializer.Deserialize<Guid[]>(lastSceneIdName);
|
||||
foreach (var sceneId in lastScenes)
|
||||
@@ -464,7 +459,7 @@ namespace FlaxEditor
|
||||
}
|
||||
|
||||
// Restore view
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out string lastSceneSpawnName))
|
||||
if (ProjectCache.TryGetCustomData(ProjectDataLastSceneSpawn, out var lastSceneSpawnName))
|
||||
Windows.EditWin.Viewport.ViewRay = JsonSerializer.Deserialize<Ray>(lastSceneSpawnName);
|
||||
}
|
||||
break;
|
||||
@@ -490,8 +485,6 @@ namespace FlaxEditor
|
||||
{
|
||||
StateMachine.CurrentState.UpdateFPS();
|
||||
}
|
||||
|
||||
EditorUpdate?.Invoke();
|
||||
|
||||
// Update modules
|
||||
for (int i = 0; i < _modules.Count; i++)
|
||||
@@ -1371,7 +1364,6 @@ namespace FlaxEditor
|
||||
public byte AutoReloadScriptsOnMainWindowFocus;
|
||||
public byte ForceScriptCompilationOnStartup;
|
||||
public byte UseAssetImportPathRelative;
|
||||
public byte EnableParticlesPreview;
|
||||
public byte AutoRebuildCSG;
|
||||
public float AutoRebuildCSGTimeoutMs;
|
||||
public byte AutoRebuildNavMesh;
|
||||
|
||||
@@ -5,10 +5,8 @@ using System.IO;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI.Drag;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Utilities;
|
||||
|
||||
namespace FlaxEditor.GUI
|
||||
{
|
||||
@@ -105,9 +103,9 @@ namespace FlaxEditor.GUI
|
||||
|
||||
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 />
|
||||
public override void Draw()
|
||||
@@ -149,13 +147,6 @@ namespace FlaxEditor.GUI
|
||||
style.Foreground,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
Render2D.DrawText(
|
||||
style.FontSmall,
|
||||
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
|
||||
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
|
||||
style.ForegroundGrey,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
}
|
||||
}
|
||||
// Check if has no item but has an asset (eg. virtual asset)
|
||||
@@ -178,13 +169,6 @@ namespace FlaxEditor.GUI
|
||||
style.Foreground,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
Render2D.DrawText(
|
||||
style.FontSmall,
|
||||
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
|
||||
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
|
||||
style.ForegroundGrey,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -192,24 +176,6 @@ namespace FlaxEditor.GUI
|
||||
// No element selected
|
||||
Render2D.FillRectangle(iconRect, style.BackgroundNormal);
|
||||
Render2D.DrawText(style.FontMedium, "No asset\nselected", iconRect, Color.Orange, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
|
||||
float sizeForTextLeft = Width - button1Rect.Right;
|
||||
if (sizeForTextLeft > 30)
|
||||
{
|
||||
Render2D.DrawText(
|
||||
style.FontSmall,
|
||||
$"None",
|
||||
new Rectangle(button1Rect.Right + 2, 0, sizeForTextLeft, ButtonsSize),
|
||||
style.Foreground,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
Render2D.DrawText(
|
||||
style.FontSmall,
|
||||
$"{TypeUtils.GetTypeDisplayName(Validator.AssetType.Type)}",
|
||||
new Rectangle(button1Rect.Right + 2, ButtonsSize + 2, sizeForTextLeft, ButtonsSize),
|
||||
style.ForegroundGrey,
|
||||
TextAlignment.Near,
|
||||
TextAlignment.Center);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if drag is over
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace FlaxEditor.GUI
|
||||
{
|
||||
@@ -44,20 +43,10 @@ namespace FlaxEditor.GUI
|
||||
public Color TitleColor = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// The column title background color.
|
||||
/// The column title background background.
|
||||
/// </summary>
|
||||
public Color TitleBackgroundColor = Color.Brown;
|
||||
|
||||
/// <summary>
|
||||
/// The column title horizontal text alignment
|
||||
/// </summary>
|
||||
public TextAlignment TitleAlignment = TextAlignment.Near;
|
||||
|
||||
/// <summary>
|
||||
/// The column title margin.
|
||||
/// </summary>
|
||||
public Margin TitleMargin = new Margin(4, 4, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The minimum size (in pixels) of the column.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
#define USE_IS_FOREGROUND
|
||||
#else
|
||||
#endif
|
||||
#if PLATFORM_SDL
|
||||
#define USE_SDL_WORKAROUNDS
|
||||
#endif
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
@@ -114,7 +111,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shows the empty menu popup on a screen.
|
||||
/// Shows the empty menu popup o na screen.
|
||||
/// </summary>
|
||||
/// <param name="control">The target control.</param>
|
||||
/// <param name="area">The target control area to cover.</param>
|
||||
@@ -218,7 +215,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
desc.AllowMaximize = false;
|
||||
desc.AllowDragAndDrop = false;
|
||||
desc.IsTopmost = true;
|
||||
desc.Type = WindowType.Utility;
|
||||
desc.IsRegularWindow = false;
|
||||
desc.HasSizingFrame = false;
|
||||
OnWindowCreating(ref desc);
|
||||
_window = Platform.CreateWindow(ref desc);
|
||||
@@ -231,6 +228,8 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
|
||||
// Show
|
||||
Visible = true;
|
||||
if (_window == null)
|
||||
return;
|
||||
_window.Show();
|
||||
PerformLayout();
|
||||
_previouslyFocused = parentWin.FocusedControl;
|
||||
@@ -379,11 +378,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_SDL_WORKAROUNDS
|
||||
private void OnWindowGotFocus()
|
||||
{
|
||||
}
|
||||
#else
|
||||
private void OnWindowGotFocus()
|
||||
{
|
||||
var child = _childCM;
|
||||
@@ -397,7 +391,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private void OnWindowLostFocus()
|
||||
{
|
||||
@@ -496,12 +489,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
// Let root context menu to check if none of the popup windows
|
||||
if (_parentCM == null && !IsForeground)
|
||||
{
|
||||
#if USE_SDL_WORKAROUNDS
|
||||
if (!IsMouseOver)
|
||||
Hide();
|
||||
#else
|
||||
Hide();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
private bool _disableEvents;
|
||||
private bool _useDynamicEditing;
|
||||
private bool _activeEyedropper;
|
||||
private bool _canPassLastChangeEvent = true;
|
||||
private ColorValueBox.ColorPickerEvent _onChanged;
|
||||
private ColorValueBox.ColorPickerClosedEvent _onClosed;
|
||||
|
||||
@@ -120,8 +119,10 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
_onClosed = pickerClosed;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Selector
|
||||
_cSelector = new ColorSelectorWithSliders(180, 18)
|
||||
@@ -381,7 +382,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
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));
|
||||
Render2D.FillRectangle(rect, Color.Gray);
|
||||
@@ -396,7 +397,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
{
|
||||
// Auto cancel on lost focus
|
||||
#if !PLATFORM_LINUX
|
||||
((WindowRootControl)Root).Window.LostFocus += OnWindowLostFocus;
|
||||
((WindowRootControl)Root).Window.LostFocus += OnCancel;
|
||||
#endif
|
||||
|
||||
base.OnShow();
|
||||
@@ -505,7 +506,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
BackgroundColorHighlighted = savedColor,
|
||||
BackgroundColorSelected = savedColor.RGBMultiplied(0.8f),
|
||||
};
|
||||
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
|
||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||
_savedColorButtons.Add(savedColorButton);
|
||||
}
|
||||
if (_savedColors.Count < 8)
|
||||
@@ -517,24 +518,11 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
TooltipText = "Save Color.",
|
||||
Tag = null,
|
||||
};
|
||||
savedColorButton.ButtonClicked += OnSavedColorButtonClicked;
|
||||
savedColorButton.ButtonClicked += (b) => OnSavedColorButtonClicked(b);
|
||||
_savedColorButtons.Add(savedColorButton);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnWindowLostFocus()
|
||||
{
|
||||
// Auto apply color on defocus
|
||||
var autoAcceptColorPickerChange = Editor.Instance.Options.Options.Interface.AutoAcceptColorPickerChange;
|
||||
if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent && autoAcceptColorPickerChange)
|
||||
{
|
||||
_canPassLastChangeEvent = false;
|
||||
_onChanged?.Invoke(_value, false);
|
||||
}
|
||||
|
||||
OnCancel();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSubmit()
|
||||
{
|
||||
@@ -559,9 +547,8 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
_disableEvents = true;
|
||||
|
||||
// Restore color if modified
|
||||
if (_useDynamicEditing && _initialValue != _value && _canPassLastChangeEvent)
|
||||
if (_useDynamicEditing && _initialValue != _value)
|
||||
{
|
||||
_canPassLastChangeEvent = false;
|
||||
_onChanged?.Invoke(_initialValue, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,9 @@ namespace FlaxEditor.GUI.Docking
|
||||
Proxy.Window.MouseUp += OnMouseUp;
|
||||
Proxy.Window.MouseMove += OnMouseMove;
|
||||
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
|
||||
Proxy.Window.GUI.PerformLayout();
|
||||
@@ -75,16 +77,13 @@ namespace FlaxEditor.GUI.Docking
|
||||
// Update rectangles
|
||||
UpdateRects();
|
||||
|
||||
// Hide base window
|
||||
window.Hide();
|
||||
|
||||
// Enable hit window presentation
|
||||
Proxy.Window.RenderingEnabled = true;
|
||||
Proxy.Window.Show();
|
||||
Proxy.Window.Focus();
|
||||
|
||||
// Hide base window
|
||||
window.Hide();
|
||||
|
||||
// Start tracking mouse
|
||||
Proxy.Window.StartTrackingMouse(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -102,8 +101,6 @@ namespace FlaxEditor.GUI.Docking
|
||||
Proxy.Window.MouseUp -= OnMouseUp;
|
||||
Proxy.Window.MouseMove -= OnMouseMove;
|
||||
Proxy.Window.LostFocus -= OnLostFocus;
|
||||
if (_toMove?.Window?.Window)
|
||||
_toMove.Window.Window.MouseUp -= OnMouseUp;
|
||||
|
||||
// Hide the proxy
|
||||
Proxy.Hide();
|
||||
@@ -441,7 +438,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
settings.AllowMinimize = false;
|
||||
settings.HasBorder = false;
|
||||
settings.HasSizingFrame = false;
|
||||
settings.Type = WindowType.Utility;
|
||||
settings.IsRegularWindow = false;
|
||||
settings.SupportsTransparency = true;
|
||||
settings.ShowInTaskbar = false;
|
||||
settings.ShowAfterFirstPaint = false;
|
||||
@@ -473,7 +470,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
settings.AllowMinimize = false;
|
||||
settings.HasBorder = false;
|
||||
settings.HasSizingFrame = false;
|
||||
settings.Type = WindowType.Utility;
|
||||
settings.IsRegularWindow = false;
|
||||
settings.SupportsTransparency = true;
|
||||
settings.ShowInTaskbar = false;
|
||||
settings.ActivateWhenFirstShown = false;
|
||||
|
||||
@@ -629,7 +629,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
|
||||
internal void MoveTabRight(int index)
|
||||
{
|
||||
if (index < _tabs.Count - 1)
|
||||
if (index < _tabs.Count - 2)
|
||||
{
|
||||
var tab = _tabs[index];
|
||||
_tabs.RemoveAt(index);
|
||||
|
||||
@@ -51,7 +51,6 @@ namespace FlaxEditor.GUI.Docking
|
||||
public DockWindow StartDragAsyncWindow;
|
||||
|
||||
private Rectangle HeaderRectangle => new Rectangle(0, 0, Width, DockPanel.DefaultHeaderHeight);
|
||||
private bool IsSingleFloatingWindow => _panel.TabsCount == 1 && _panel.IsFloating && _panel.ChildPanelsCount == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DockPanelProxy"/> class.
|
||||
@@ -188,10 +187,6 @@ namespace FlaxEditor.GUI.Docking
|
||||
var headerRect = HeaderRectangle;
|
||||
var tabsCount = _panel.TabsCount;
|
||||
|
||||
// Return and don't draw tab if only 1 window and it is floating
|
||||
if (IsSingleFloatingWindow)
|
||||
return;
|
||||
|
||||
// Check if has only one window docked
|
||||
if (tabsCount == 1)
|
||||
{
|
||||
@@ -326,9 +321,6 @@ namespace FlaxEditor.GUI.Docking
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
||||
{
|
||||
if (IsSingleFloatingWindow)
|
||||
return base.OnMouseDoubleClick(location, button);
|
||||
|
||||
// Maximize/restore on double click
|
||||
var tab = GetTabAtPos(location, out _);
|
||||
var rootWindow = tab?.RootWindow;
|
||||
@@ -347,8 +339,6 @@ namespace FlaxEditor.GUI.Docking
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||
{
|
||||
if (IsSingleFloatingWindow)
|
||||
return base.OnMouseDown(location, button);
|
||||
MouseDownWindow = GetTabAtPos(location, out IsMouseDownOverCross);
|
||||
|
||||
// Check buttons
|
||||
@@ -378,9 +368,6 @@ namespace FlaxEditor.GUI.Docking
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
if (IsSingleFloatingWindow)
|
||||
return base.OnMouseUp(location, button);
|
||||
|
||||
// Check tabs under mouse position at the beginning and at the end
|
||||
var tab = GetTabAtPos(location, out var overCross);
|
||||
|
||||
@@ -423,7 +410,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
public override void OnMouseMove(Float2 location)
|
||||
{
|
||||
MousePosition = location;
|
||||
if (IsMouseLeftButtonDown && !IsSingleFloatingWindow)
|
||||
if (IsMouseLeftButtonDown)
|
||||
{
|
||||
// Check if mouse is outside the header
|
||||
if (!HeaderRectangle.Contains(location))
|
||||
@@ -514,10 +501,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
/// <inheritdoc />
|
||||
public override void GetDesireClientArea(out Rectangle rect)
|
||||
{
|
||||
if (IsSingleFloatingWindow)
|
||||
rect = new Rectangle(0, 0, Width, Height);
|
||||
else
|
||||
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
|
||||
rect = new Rectangle(0, DockPanel.DefaultHeaderHeight, Width, Height - DockPanel.DefaultHeaderHeight);
|
||||
}
|
||||
|
||||
private DragDropEffect TrySelectTabUnderLocation(ref Float2 location)
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
settings.AllowMaximize = true;
|
||||
settings.AllowDragAndDrop = true;
|
||||
settings.IsTopmost = false;
|
||||
settings.Type = WindowType.Regular;
|
||||
settings.IsRegularWindow = true;
|
||||
settings.HasSizingFrame = true;
|
||||
settings.ShowAfterFirstPaint = false;
|
||||
settings.ShowInTaskbar = true;
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Input
|
||||
base.Draw();
|
||||
|
||||
var style = Style.Current;
|
||||
var r = new Rectangle(0, 0, Width, Height);
|
||||
var r = new Rectangle(2, 2, Width - 4, Height - 4);
|
||||
|
||||
Render2D.FillRectangle(r, _value);
|
||||
Render2D.DrawRectangle(r, IsMouseOver || IsNavFocused ? style.BackgroundSelected : Color.Black);
|
||||
|
||||
@@ -132,8 +132,6 @@ namespace FlaxEditor.GUI.Input
|
||||
_isSliding = false;
|
||||
EndMouseCapture();
|
||||
SlidingEnd?.Invoke();
|
||||
Defocus();
|
||||
Parent?.Focus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -185,8 +183,6 @@ namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
// Click change
|
||||
Value += (mousePosition < _thumbCenter ? -1 : 1) * 10;
|
||||
Defocus();
|
||||
Parent?.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,10 +197,6 @@ namespace FlaxEditor.GUI.Input
|
||||
// Update sliding
|
||||
var slidePosition = location + Root.TrackingMouseOffset;
|
||||
Value = Mathf.Remap(slidePosition.X, 4, TrackSize - 4, Minimum, Maximum);
|
||||
if (Mathf.NearEqual(Value, Maximum))
|
||||
Value = Maximum;
|
||||
else if (Mathf.NearEqual(Value, Minimum))
|
||||
Value = Minimum;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -372,7 +364,7 @@ namespace FlaxEditor.GUI.Input
|
||||
};
|
||||
_slider.ValueChanged += SliderOnValueChanged;
|
||||
_slider.SlidingStart += SlidingStart;
|
||||
_slider.SlidingEnd += SliderOnSliderEnd;
|
||||
_slider.SlidingEnd += SlidingEnd;
|
||||
_textBox = new TextBox(false, split, 0)
|
||||
{
|
||||
Text = _value.ToString(CultureInfo.InvariantCulture),
|
||||
@@ -383,13 +375,6 @@ namespace FlaxEditor.GUI.Input
|
||||
_textBox.EditEnd += OnTextBoxEditEnd;
|
||||
}
|
||||
|
||||
private void SliderOnSliderEnd()
|
||||
{
|
||||
SlidingEnd?.Invoke();
|
||||
Defocus();
|
||||
Parent?.Focus();
|
||||
}
|
||||
|
||||
private void SliderOnValueChanged()
|
||||
{
|
||||
if (_valueIsChanging)
|
||||
@@ -412,8 +397,6 @@ namespace FlaxEditor.GUI.Input
|
||||
{
|
||||
UpdateText();
|
||||
}
|
||||
Defocus();
|
||||
Parent?.Focus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -266,7 +266,6 @@ namespace FlaxEditor.GUI.Input
|
||||
return base.OnMouseDown(location, button);
|
||||
}
|
||||
|
||||
#if !PLATFORM_SDL
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMove(Float2 location)
|
||||
{
|
||||
@@ -293,36 +292,6 @@ namespace FlaxEditor.GUI.Input
|
||||
base.OnMouseMove(location);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseMoveRelative(Float2 mouseMotion)
|
||||
{
|
||||
var location = Root.TrackingMouseOffset;
|
||||
if (_isSliding)
|
||||
{
|
||||
// Update sliding
|
||||
ApplySliding(Root.TrackingMouseOffset.X * _slideSpeed);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update cursor type so user knows they can slide value
|
||||
if (CanUseSliding && SlideRect.Contains(location) && !_isSliding)
|
||||
{
|
||||
Cursor = CursorType.SizeWE;
|
||||
_cursorChanged = true;
|
||||
}
|
||||
else if (_cursorChanged && !_isSliding)
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
_cursorChanged = false;
|
||||
}
|
||||
|
||||
base.OnMouseMoveRelative(mouseMotion);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
||||
{
|
||||
|
||||
@@ -23,9 +23,6 @@ namespace FlaxEditor.GUI
|
||||
[HideInEditor]
|
||||
public class Item : Control
|
||||
{
|
||||
private bool _isStartsWithMatch;
|
||||
private bool _isFullMatch;
|
||||
|
||||
/// <summary>
|
||||
/// The is mouse down flag.
|
||||
/// </summary>
|
||||
@@ -46,11 +43,6 @@ namespace FlaxEditor.GUI
|
||||
/// </summary>
|
||||
public string Category;
|
||||
|
||||
/// <summary>
|
||||
/// A computed score for the context menu order
|
||||
/// </summary>
|
||||
public float SortScore;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when items gets clicked by the user.
|
||||
/// </summary>
|
||||
@@ -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>
|
||||
/// Updates the filter.
|
||||
/// </summary>
|
||||
/// <param name="filterText">The filter text.</param>
|
||||
public void UpdateFilter(string filterText)
|
||||
{
|
||||
_isStartsWithMatch = _isFullMatch = false;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(filterText))
|
||||
{
|
||||
// Clear filter
|
||||
_highlights?.Clear();
|
||||
Visible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (QueryFilterHelper.Match(filterText, Name, out var ranges))
|
||||
else
|
||||
{
|
||||
// Update highlights
|
||||
if (_highlights == null)
|
||||
_highlights = new List<Rectangle>(ranges.Length);
|
||||
else
|
||||
_highlights.Clear();
|
||||
var style = Style.Current;
|
||||
var font = style.FontSmall;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
if (QueryFilterHelper.Match(filterText, Name, out var ranges))
|
||||
{
|
||||
var start = font.GetCharPosition(Name, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
|
||||
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
|
||||
|
||||
if (ranges[i].StartIndex <= 0)
|
||||
// Update highlights
|
||||
if (_highlights == null)
|
||||
_highlights = new List<Rectangle>(ranges.Length);
|
||||
else
|
||||
_highlights.Clear();
|
||||
var style = Style.Current;
|
||||
var font = style.FontSmall;
|
||||
for (int i = 0; i < ranges.Length; i++)
|
||||
{
|
||||
_isStartsWithMatch = true;
|
||||
if (ranges[i].Length == Name.Length)
|
||||
_isFullMatch = true;
|
||||
var start = font.GetCharPosition(Name, ranges[i].StartIndex);
|
||||
var end = font.GetCharPosition(Name, ranges[i].EndIndex);
|
||||
_highlights.Add(new Rectangle(start.X + 2, 0, end.X - start.X, Height));
|
||||
}
|
||||
Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hide
|
||||
_highlights?.Clear();
|
||||
Visible = false;
|
||||
}
|
||||
Visible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide
|
||||
_highlights?.Clear();
|
||||
Visible = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -211,14 +178,7 @@ namespace FlaxEditor.GUI
|
||||
public override int Compare(Control other)
|
||||
{
|
||||
if (other is Item otherItem)
|
||||
{
|
||||
int order = -1 * SortScore.CompareTo(otherItem.SortScore);
|
||||
if (order == 0)
|
||||
{
|
||||
order = string.Compare(Name, otherItem.Name, StringComparison.Ordinal);
|
||||
}
|
||||
return order;
|
||||
}
|
||||
return string.Compare(Name, otherItem.Name, StringComparison.Ordinal);
|
||||
return base.Compare(other);
|
||||
}
|
||||
}
|
||||
@@ -289,10 +249,7 @@ namespace FlaxEditor.GUI
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
if (items[i] is Item item)
|
||||
{
|
||||
item.UpdateFilter(_searchBox.Text);
|
||||
item.UpdateScore();
|
||||
}
|
||||
}
|
||||
if (_categoryPanels != null)
|
||||
{
|
||||
@@ -305,7 +262,6 @@ namespace FlaxEditor.GUI
|
||||
if (category.Children[j] is Item item2)
|
||||
{
|
||||
item2.UpdateFilter(_searchBox.Text);
|
||||
item2.UpdateScore();
|
||||
anyVisible |= item2.Visible;
|
||||
}
|
||||
}
|
||||
@@ -317,8 +273,6 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
}
|
||||
|
||||
SortItems();
|
||||
|
||||
UnlockChildrenRecursive();
|
||||
PerformLayout(true);
|
||||
_searchBox.Focus();
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace FlaxEditor.GUI
|
||||
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
|
||||
public sealed class MainMenu : ContainerControl
|
||||
{
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
private bool _useCustomWindowSystem;
|
||||
private Image _icon;
|
||||
private Label _title;
|
||||
@@ -67,7 +67,7 @@ namespace FlaxEditor.GUI
|
||||
AutoFocus = false;
|
||||
AnchorPreset = AnchorPresets.HorizontalStretchTop;
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
_useCustomWindowSystem = !Editor.Instance.Options.Options.Interface.UseNativeWindowSystem;
|
||||
if (_useCustomWindowSystem)
|
||||
{
|
||||
@@ -166,7 +166,7 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
/// <inheritdoc />
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
@@ -291,7 +291,7 @@ namespace FlaxEditor.GUI
|
||||
if (base.OnMouseDoubleClick(location, button))
|
||||
return true;
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
var child = GetChildAtRecursive(location);
|
||||
if (_useCustomWindowSystem && child is not Button && child is not MainMenuButton)
|
||||
{
|
||||
@@ -321,7 +321,7 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
float x = 0;
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
if (_useCustomWindowSystem)
|
||||
{
|
||||
// Icon
|
||||
@@ -349,7 +349,7 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
if (_useCustomWindowSystem)
|
||||
{
|
||||
// Buttons
|
||||
@@ -367,7 +367,7 @@ namespace FlaxEditor.GUI
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace FlaxEditor.GUI
|
||||
Text = text;
|
||||
|
||||
var style = Style.Current;
|
||||
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||
#if PLATFORM_WINDOWS
|
||||
if (Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
|
||||
{
|
||||
BackgroundColorMouseOver = style.BackgroundHighlighted;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace FlaxEditor.GUI
|
||||
ContentItem = item;
|
||||
ContentItem.AddReference(this);
|
||||
|
||||
OnItemRenamed(item);
|
||||
Name = item.ShortName;
|
||||
TooltipText = item.Path;
|
||||
|
||||
Height = IconSize + 4;
|
||||
@@ -82,9 +82,7 @@ namespace FlaxEditor.GUI
|
||||
/// <inheritdoc />
|
||||
public void OnItemRenamed(ContentItem item)
|
||||
{
|
||||
Name = item.ShortName;
|
||||
if (item is ScriptItem)
|
||||
Name = item.FileName; // Show extension for scripts (esp. for .h and .cpp files of the same name)
|
||||
Name = ContentItem.ShortName;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -130,14 +130,12 @@ namespace FlaxEditor.GUI
|
||||
|
||||
var style = Style.Current;
|
||||
var font = column.TitleFont ?? style.FontMedium;
|
||||
var textRect = rect;
|
||||
column.TitleMargin.ShrinkRectangle(ref textRect);
|
||||
Render2D.DrawText(font, column.Title, textRect, column.TitleColor, column.TitleAlignment, TextAlignment.Center);
|
||||
Render2D.DrawText(font, column.Title, rect, column.TitleColor, TextAlignment.Center, TextAlignment.Center);
|
||||
|
||||
if (columnIndex < _columns.Length - 1)
|
||||
{
|
||||
var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
|
||||
Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : style.Background * 0.9f);
|
||||
var splitRect = new Rectangle(rect.Right - 1, 2, 2, rect.Height - 4);
|
||||
Render2D.FillRectangle(splitRect, _movingSplit == columnIndex || splitRect.Contains(_mousePos) ? style.BorderNormal : column.TitleBackgroundColor * 0.9f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +151,7 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
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))
|
||||
{
|
||||
// Start moving splitter
|
||||
@@ -195,31 +193,6 @@ namespace FlaxEditor.GUI
|
||||
|
||||
PerformLayout();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_columns != null && _splits != null)
|
||||
{
|
||||
Rectangle rect = new Rectangle(0, 0, 0, _headerHeight);
|
||||
for (int i = 0; i < _columns.Length - 1; i++)
|
||||
{
|
||||
rect.Width = GetColumnWidth(i);
|
||||
|
||||
var splitRect = new Rectangle(rect.Right - 2, 2, 4, rect.Height - 4);
|
||||
if (splitRect.Contains(location))
|
||||
{
|
||||
// Start moving splitter
|
||||
Cursor = CursorType.SizeWE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
}
|
||||
|
||||
rect.X += rect.Width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnMouseMove(location);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
/// The keyframes.
|
||||
/// </summary>
|
||||
[EditorDisplay("Keyframes", EditorDisplayAttribute.InlineStyle), ExpandGroups]
|
||||
[Collection(CanReorderItems = false, CanResize = true)]
|
||||
[Collection(CanReorderItems = false, ReadOnly = true)]
|
||||
public List<KeyValuePair<string, object>> Keyframes;
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user