Compare commits
50 Commits
emscripten
...
sdl_platfo
| Author | SHA1 | Date | |
|---|---|---|---|
| 43c4d45080 | |||
| 56a85f6ac0 | |||
| 1b8e25cb86 | |||
| 7088ce8742 | |||
| c7326ea483 | |||
| 523cad3b2c | |||
| ff6816396c | |||
| 24b8ad77fe | |||
| 3008d8037d | |||
| 0973363c64 | |||
| 5d45b9ea1c | |||
| c40f7c12f2 | |||
| 1b2d6372b2 | |||
| 0782ea889c | |||
| ef89501111 | |||
| 608353b996 | |||
| 221325ef09 | |||
| 8f57c91a9e | |||
| 968de34cae | |||
| 6586a98f8d | |||
| b3510b0e44 | |||
| d5a92c1942 | |||
| 417f82826f | |||
| 63bed0986a | |||
| c40eefc79d | |||
| d68631dd20 | |||
| e77b772010 | |||
| e41e956386 | |||
| 33e47c646b | |||
| b30ce6b84f | |||
| 02f67b25f3 | |||
| 469a422681 | |||
| 42fa0ffdd1 | |||
| f97ee72f1c | |||
| 89c93dd4f7 | |||
| 60cd8f702e | |||
| f376ec5c8a | |||
| 82bb297119 | |||
| ed994cb560 | |||
| 8efe2134f0 | |||
| 8efc4715c6 | |||
| 48c60144ae | |||
| 249cde467e | |||
| e2eadc87b6 | |||
| bc4b94d2bc | |||
| ecf074801f | |||
| 74bac97f44 | |||
| d7eebb699c | |||
| dde07bac8d | |||
| 5c8e593d89 |
3
.github/workflows/build_linux.yml
vendored
3
.github/workflows/build_linux.yml
vendored
@@ -16,8 +16,7 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
||||||
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
|
|||||||
6
.github/workflows/cd.yml
vendored
6
.github/workflows/cd.yml
vendored
@@ -87,8 +87,7 @@ jobs:
|
|||||||
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
||||||
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
@@ -119,8 +118,7 @@ jobs:
|
|||||||
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
||||||
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
|
|||||||
3
.github/workflows/tests.yml
vendored
3
.github/workflows/tests.yml
vendored
@@ -28,8 +28,7 @@ jobs:
|
|||||||
git lfs pull
|
git lfs pull
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
||||||
sudo apt-get install -y --fix-missing libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
|
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Redirect to our own Git LFS server
|
# Redirect to our own Git LFS server
|
||||||
[lfs]
|
[lfs]
|
||||||
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||||
locksverify = false
|
locksverify = false
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,8 +4,8 @@
|
|||||||
#define MAX_LOCAL_LIGHTS 4
|
#define MAX_LOCAL_LIGHTS 4
|
||||||
@1// Forward Shading: Includes
|
@1// Forward Shading: Includes
|
||||||
#include "./Flax/LightingCommon.hlsl"
|
#include "./Flax/LightingCommon.hlsl"
|
||||||
#include "./Flax/ReflectionsCommon.hlsl"
|
|
||||||
#if USE_REFLECTIONS
|
#if USE_REFLECTIONS
|
||||||
|
#include "./Flax/ReflectionsCommon.hlsl"
|
||||||
#define MATERIAL_REFLECTIONS_SSR 1
|
#define MATERIAL_REFLECTIONS_SSR 1
|
||||||
#if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR
|
#if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR
|
||||||
#include "./Flax/SSR.hlsl"
|
#include "./Flax/SSR.hlsl"
|
||||||
@@ -14,13 +14,11 @@
|
|||||||
#include "./Flax/Lighting.hlsl"
|
#include "./Flax/Lighting.hlsl"
|
||||||
#include "./Flax/ShadowsSampling.hlsl"
|
#include "./Flax/ShadowsSampling.hlsl"
|
||||||
#include "./Flax/ExponentialHeightFog.hlsl"
|
#include "./Flax/ExponentialHeightFog.hlsl"
|
||||||
#include "./Flax/VolumetricFog.hlsl"
|
|
||||||
@2// Forward Shading: Constants
|
@2// Forward Shading: Constants
|
||||||
LightData DirectionalLight;
|
LightData DirectionalLight;
|
||||||
LightData SkyLight;
|
LightData SkyLight;
|
||||||
EnvProbeData EnvironmentProbe;
|
ProbeData EnvironmentProbe;
|
||||||
ExponentialHeightFogData ExponentialHeightFog;
|
ExponentialHeightFogData ExponentialHeightFog;
|
||||||
VolumetricFogData VolumetricFog;
|
|
||||||
float3 Dummy2;
|
float3 Dummy2;
|
||||||
uint LocalLightsCount;
|
uint LocalLightsCount;
|
||||||
LightData LocalLights[MAX_LOCAL_LIGHTS];
|
LightData LocalLights[MAX_LOCAL_LIGHTS];
|
||||||
@@ -30,14 +28,12 @@ TextureCube SkyLightTexture : register(t__SRV__);
|
|||||||
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
Buffer<float4> ShadowsBuffer : register(t__SRV__);
|
||||||
Texture2D<float> ShadowMap : register(t__SRV__);
|
Texture2D<float> ShadowMap : register(t__SRV__);
|
||||||
Texture3D VolumetricFogTexture : register(t__SRV__);
|
Texture3D VolumetricFogTexture : register(t__SRV__);
|
||||||
Texture2D PreIntegratedGF : register(t__SRV__);
|
|
||||||
@4// Forward Shading: Utilities
|
@4// Forward Shading: Utilities
|
||||||
// Public accessors for lighting data, use them as data binding might change but those methods will remain.
|
// Public accessors for lighting data, use them as data binding might change but those methods will remain.
|
||||||
LightData GetDirectionalLight() { return DirectionalLight; }
|
LightData GetDirectionalLight() { return DirectionalLight; }
|
||||||
LightData GetSkyLight() { return SkyLight; }
|
LightData GetSkyLight() { return SkyLight; }
|
||||||
EnvProbeData GetEnvironmentProbe() { return EnvironmentProbe; }
|
ProbeData GetEnvironmentProbe() { return EnvironmentProbe; }
|
||||||
ExponentialHeightFogData GetExponentialHeightFog() { return ExponentialHeightFog; }
|
ExponentialHeightFogData GetExponentialHeightFog() { return ExponentialHeightFog; }
|
||||||
VolumetricFogData GetVolumetricFog() { return VolumetricFog; }
|
|
||||||
uint GetLocalLightsCount() { return LocalLightsCount; }
|
uint GetLocalLightsCount() { return LocalLightsCount; }
|
||||||
LightData GetLocalLight(uint i) { return LocalLights[i]; }
|
LightData GetLocalLight(uint i) { return LocalLights[i]; }
|
||||||
@5// Forward Shading: Shaders
|
@5// Forward Shading: Shaders
|
||||||
@@ -112,8 +108,7 @@ void PS_Forward(
|
|||||||
|
|
||||||
// Calculate reflections
|
// Calculate reflections
|
||||||
#if USE_REFLECTIONS
|
#if USE_REFLECTIONS
|
||||||
float4 reflections = SampleReflectionProbe(ViewPos, EnvProbe, EnvironmentProbe, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness);
|
float3 reflections = SampleReflectionProbe(ViewPos, EnvProbe, EnvironmentProbe, gBuffer.WorldPos, gBuffer.Normal, gBuffer.Roughness).rgb;
|
||||||
reflections.rgb *= reflections.a;
|
|
||||||
|
|
||||||
#if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR
|
#if MATERIAL_REFLECTIONS == MATERIAL_REFLECTIONS_SSR
|
||||||
// Screen Space Reflections
|
// Screen Space Reflections
|
||||||
@@ -121,7 +116,7 @@ void PS_Forward(
|
|||||||
Texture2D sceneColorTexture = MATERIAL_REFLECTIONS_SSR_COLOR;
|
Texture2D sceneColorTexture = MATERIAL_REFLECTIONS_SSR_COLOR;
|
||||||
float2 screenUV = materialInput.SvPosition.xy * ScreenSize.zw;
|
float2 screenUV = materialInput.SvPosition.xy * ScreenSize.zw;
|
||||||
float stepSize = ScreenSize.z; // 1 / screenWidth
|
float stepSize = ScreenSize.z; // 1 / screenWidth
|
||||||
float maxSamples = 50;
|
float maxSamples = 48;
|
||||||
float worldAntiSelfOcclusionBias = 0.1f;
|
float worldAntiSelfOcclusionBias = 0.1f;
|
||||||
float brdfBias = 0.82f;
|
float brdfBias = 0.82f;
|
||||||
float drawDistance = 5000.0f;
|
float drawDistance = 5000.0f;
|
||||||
@@ -129,7 +124,7 @@ void PS_Forward(
|
|||||||
if (hit.z > 0)
|
if (hit.z > 0)
|
||||||
{
|
{
|
||||||
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
||||||
reflections.rgb = lerp(reflections.rgb, screenColor, hit.z);
|
reflections = lerp(reflections, screenColor, hit.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to software tracing if possible
|
// Fallback to software tracing if possible
|
||||||
@@ -141,17 +136,17 @@ void PS_Forward(
|
|||||||
if (TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas))
|
if (TraceSDFSoftwareReflections(gBuffer, reflectWS, surfaceAtlas))
|
||||||
{
|
{
|
||||||
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
float3 screenColor = sceneColorTexture.SampleLevel(SamplerPointClamp, hit.xy, 0).rgb;
|
||||||
reflections.rgb = lerp(surfaceAtlas, float4(screenColor, 1), hit.z);
|
reflections = lerp(surfaceAtlas, float4(screenColor, 1), hit.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
light.rgb += reflections.rgb * GetReflectionSpecularLighting(PreIntegratedGF, ViewPos, gBuffer);
|
light.rgb += reflections * GetReflectionSpecularLighting(ViewPos, gBuffer) * light.a;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Add lighting
|
// Add lighting (apply ambient occlusion)
|
||||||
output.rgb += light.rgb;
|
output.rgb += light.rgb * gBuffer.AO;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -163,13 +158,17 @@ void PS_Forward(
|
|||||||
#else
|
#else
|
||||||
float fogSceneDistance = gBuffer.ViewPos.z;
|
float fogSceneDistance = gBuffer.ViewPos.z;
|
||||||
#endif
|
#endif
|
||||||
float fogSkipDistance = max(ExponentialHeightFog.VolumetricFogMaxDistance - 100, 0);
|
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, 0, fogSceneDistance);
|
||||||
float4 fog = GetExponentialHeightFog(ExponentialHeightFog, materialInput.WorldPosition, ViewPos, fogSkipDistance, fogSceneDistance);
|
|
||||||
if (ExponentialHeightFog.VolumetricFogMaxDistance > 0)
|
if (ExponentialHeightFog.VolumetricFogMaxDistance > 0)
|
||||||
{
|
{
|
||||||
// Sample volumetric fog and mix it in
|
// Sample volumetric fog and mix it in
|
||||||
float2 screenUV = materialInput.SvPosition.xy * ScreenSize.zw;
|
float2 screenUV = materialInput.SvPosition.xy * ScreenSize.zw;
|
||||||
float4 volumetricFog = SampleVolumetricFog(VolumetricFogTexture, VolumetricFog, materialInput.WorldPosition - ViewPos, screenUV, TemporalAAJitter);
|
float3 viewVector = materialInput.WorldPosition - ViewPos;
|
||||||
|
float sceneDepth = length(viewVector);
|
||||||
|
float depthSlice = sceneDepth / ExponentialHeightFog.VolumetricFogMaxDistance;
|
||||||
|
float3 volumeUV = float3(screenUV, depthSlice);
|
||||||
|
float4 volumetricFog = VolumetricFogTexture.SampleLevel(SamplerLinearClamp, volumeUV, 0);
|
||||||
fog = CombineVolumetricFog(fog, volumetricFog);
|
fog = CombineVolumetricFog(fog, volumetricFog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ struct VertexOutput
|
|||||||
#endif
|
#endif
|
||||||
float4 ClipExtents : TEXCOORD3;
|
float4 ClipExtents : TEXCOORD3;
|
||||||
float2 ClipOrigin : TEXCOORD4;
|
float2 ClipOrigin : TEXCOORD4;
|
||||||
float2 CustomData : TEXCOORD5; // x-per-geometry type, y-features mask
|
|
||||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
||||||
#endif
|
#endif
|
||||||
@@ -56,7 +55,6 @@ struct PixelInput
|
|||||||
#endif
|
#endif
|
||||||
float4 ClipExtents : TEXCOORD3;
|
float4 ClipExtents : TEXCOORD3;
|
||||||
float2 ClipOrigin : TEXCOORD4;
|
float2 ClipOrigin : TEXCOORD4;
|
||||||
float2 CustomData : TEXCOORD5; // x-per-geometry type, y-features mask
|
|
||||||
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
#if USE_CUSTOM_VERTEX_INTERPOLATORS
|
||||||
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
float4 CustomVSToPS[CUSTOM_VERTEX_INTERPOLATORS_COUNT] : TEXCOORD9;
|
||||||
#endif
|
#endif
|
||||||
@@ -69,7 +67,6 @@ struct MaterialInput
|
|||||||
float3 WorldPosition;
|
float3 WorldPosition;
|
||||||
float TwoSidedSign;
|
float TwoSidedSign;
|
||||||
float2 TexCoord;
|
float2 TexCoord;
|
||||||
float2 CustomData; // x-per-geometry type, y-features mask
|
|
||||||
#if USE_VERTEX_COLOR
|
#if USE_VERTEX_COLOR
|
||||||
half4 VertexColor;
|
half4 VertexColor;
|
||||||
#endif
|
#endif
|
||||||
@@ -87,7 +84,6 @@ MaterialInput GetMaterialInput(Render2DVertex input, VertexOutput output)
|
|||||||
MaterialInput result;
|
MaterialInput result;
|
||||||
result.WorldPosition = output.WorldPosition;
|
result.WorldPosition = output.WorldPosition;
|
||||||
result.TexCoord = output.TexCoord;
|
result.TexCoord = output.TexCoord;
|
||||||
result.CustomData = input.CustomDataAndClipOrigin.xy;
|
|
||||||
#if USE_VERTEX_COLOR
|
#if USE_VERTEX_COLOR
|
||||||
result.VertexColor = output.VertexColor;
|
result.VertexColor = output.VertexColor;
|
||||||
#endif
|
#endif
|
||||||
@@ -107,7 +103,6 @@ MaterialInput GetMaterialInput(PixelInput input)
|
|||||||
MaterialInput result;
|
MaterialInput result;
|
||||||
result.WorldPosition = input.WorldPosition;
|
result.WorldPosition = input.WorldPosition;
|
||||||
result.TexCoord = input.TexCoord;
|
result.TexCoord = input.TexCoord;
|
||||||
result.CustomData = input.CustomData;
|
|
||||||
#if USE_VERTEX_COLOR
|
#if USE_VERTEX_COLOR
|
||||||
result.VertexColor = input.VertexColor;
|
result.VertexColor = input.VertexColor;
|
||||||
#endif
|
#endif
|
||||||
@@ -234,7 +229,6 @@ VertexOutput VS_GUI(Render2DVertex input)
|
|||||||
#if USE_VERTEX_COLOR
|
#if USE_VERTEX_COLOR
|
||||||
output.VertexColor = input.Color;
|
output.VertexColor = input.Color;
|
||||||
#endif
|
#endif
|
||||||
output.CustomData = input.CustomDataAndClipOrigin.xy;
|
|
||||||
output.ClipOrigin = input.CustomDataAndClipOrigin.zw;
|
output.ClipOrigin = input.CustomDataAndClipOrigin.zw;
|
||||||
output.ClipExtents = input.ClipExtents;
|
output.ClipExtents = input.ClipExtents;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "./Flax/Common.hlsl"
|
#include "./Flax/Common.hlsl"
|
||||||
#include "./Flax/MaterialCommon.hlsl"
|
#include "./Flax/MaterialCommon.hlsl"
|
||||||
#include "./Flax/GBufferCommon.hlsl"
|
#include "./Flax/GBufferCommon.hlsl"
|
||||||
#include "./Flax/VolumetricFog.hlsl"
|
|
||||||
@7
|
@7
|
||||||
|
|
||||||
// Primary constant buffer (with additional material parameters)
|
// Primary constant buffer (with additional material parameters)
|
||||||
@@ -22,7 +21,6 @@ float Dummy0;
|
|||||||
float VolumetricFogMaxDistance;
|
float VolumetricFogMaxDistance;
|
||||||
int ParticleStride;
|
int ParticleStride;
|
||||||
int ParticleIndex;
|
int ParticleIndex;
|
||||||
float4 GridSliceParameters;
|
|
||||||
@1META_CB_END
|
@1META_CB_END
|
||||||
|
|
||||||
// Particles attributes buffer
|
// Particles attributes buffer
|
||||||
@@ -204,19 +202,19 @@ Material GetMaterialPS(MaterialInput input)
|
|||||||
META_PS(true, FEATURE_LEVEL_SM5)
|
META_PS(true, FEATURE_LEVEL_SM5)
|
||||||
void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out float4 VBufferB : SV_Target1)
|
void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out float4 VBufferB : SV_Target1)
|
||||||
{
|
{
|
||||||
// Reproject grid position back to the screen and world space
|
|
||||||
uint3 gridCoordinate = uint3(input.Vertex.Position.xy, input.LayerIndex);
|
uint3 gridCoordinate = uint3(input.Vertex.Position.xy, input.LayerIndex);
|
||||||
float3 cellOffset = 0.5f;
|
float3 cellOffset = 0.5f;
|
||||||
float2 volumeUV = (gridCoordinate.xy + cellOffset.xy) / GridSize.xy;
|
float2 volumeUV = (gridCoordinate.xy + cellOffset.xy) / GridSize.xy;
|
||||||
float sceneDepth = GetDepthFromSlice(GridSliceParameters, gridCoordinate.z + cellOffset.z) / ViewFar;
|
float zSlice = gridCoordinate.z + cellOffset.z;
|
||||||
|
float sceneDepth = (zSlice / GridSize.z) * VolumetricFogMaxDistance / ViewFar;
|
||||||
float deviceDepth = (ViewInfo.w / sceneDepth) + ViewInfo.z;
|
float deviceDepth = (ViewInfo.w / sceneDepth) + ViewInfo.z;
|
||||||
float4 clipPos = float4(volumeUV * float2(2.0, -2.0) + float2(-1.0, 1.0), deviceDepth, 1.0);
|
float4 clipPos = float4(volumeUV * float2(2.0, -2.0) + float2(-1.0, 1.0), deviceDepth, 1.0);
|
||||||
float4 wsPos = mul(clipPos, InverseViewProjectionMatrix);
|
float4 wsPos = mul(clipPos, InverseViewProjectionMatrix);
|
||||||
wsPos.xyz /= wsPos.w;
|
float3 positionWS = wsPos.xyz / wsPos.w;
|
||||||
|
|
||||||
// Get material parameters
|
// Get material parameters
|
||||||
MaterialInput materialInput = (MaterialInput)0;
|
MaterialInput materialInput = (MaterialInput)0;
|
||||||
materialInput.WorldPosition = wsPos.xyz;
|
materialInput.WorldPosition = positionWS;
|
||||||
materialInput.TexCoord = input.Vertex.TexCoord;
|
materialInput.TexCoord = input.Vertex.TexCoord;
|
||||||
materialInput.ParticleIndex = ParticleIndex;
|
materialInput.ParticleIndex = ParticleIndex;
|
||||||
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
materialInput.TBN = float3x3(float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
|
||||||
@@ -227,10 +225,9 @@ void PS_VolumetricFog(Quad_GS2PS input, out float4 VBufferA : SV_Target0, out fl
|
|||||||
Material material = GetMaterialPS(materialInput);
|
Material material = GetMaterialPS(materialInput);
|
||||||
|
|
||||||
// Compute fog properties
|
// Compute fog properties
|
||||||
material.Opacity *= material.Mask;
|
|
||||||
float3 albedo = material.Color;
|
float3 albedo = material.Color;
|
||||||
float extinction = material.Opacity * 0.001f;
|
float extinction = material.Opacity * material.Mask * 0.001f;
|
||||||
float3 emission = material.Emissive * material.Opacity;
|
float3 emission = material.Emissive;
|
||||||
float3 scattering = albedo * extinction;
|
float3 scattering = albedo * extinction;
|
||||||
float absorption = max(0.0f, extinction - Luminance(scattering));
|
float absorption = max(0.0f, extinction - Luminance(scattering));
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Fog.flax
LFS
BIN
Content/Shaders/Fog.flax
LFS
Binary file not shown.
BIN
Content/Shaders/GI/DDGI.flax
LFS
BIN
Content/Shaders/GI/DDGI.flax
LFS
Binary file not shown.
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:615dff65b01507be6c4de722e126324aba20fc197f8e12dafaa94a05e46cba6e
|
oid sha256:0f34bf867df5f4296ca66ac691c2bca4efa168fb9e21ca4e613e8086669575cf
|
||||||
size 13222
|
size 13296
|
||||||
|
|||||||
BIN
Content/Shaders/GUI.flax
LFS
BIN
Content/Shaders/GUI.flax
LFS
Binary file not shown.
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:1f07ebb16820897e8598ae7a0627cb75b3d28e9dceea3ad4bd9ff543d5cdd01c
|
oid sha256:064f54786958f109222c49cbc0358ff4f345b30010fcd5e8cc1fab7bdc68c4fe
|
||||||
size 13979
|
size 13349
|
||||||
|
|||||||
BIN
Content/Shaders/Histogram.flax
LFS
BIN
Content/Shaders/Histogram.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Lights.flax
LFS
BIN
Content/Shaders/Lights.flax
LFS
Binary file not shown.
BIN
Content/Shaders/MultiScaler.flax
LFS
BIN
Content/Shaders/MultiScaler.flax
LFS
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Reflections.flax
LFS
BIN
Content/Shaders/Reflections.flax
LFS
Binary file not shown.
BIN
Content/Shaders/SSAO.flax
LFS
BIN
Content/Shaders/SSAO.flax
LFS
Binary file not shown.
BIN
Content/Shaders/SSR.flax
LFS
BIN
Content/Shaders/SSR.flax
LFS
Binary file not shown.
BIN
Content/Shaders/Sky.flax
LFS
BIN
Content/Shaders/Sky.flax
LFS
Binary file not shown.
BIN
Content/Shaders/TAA.flax
LFS
BIN
Content/Shaders/TAA.flax
LFS
Binary file not shown.
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:706adde844360c2b0e65ecabaf1d2e2cc4eb4ac7ca9d483d0dd04ec8163b3d97
|
oid sha256:872ac3560279bfd0aeb989ebac1b49750dd142b985bc40058888dfd2b63fe9b2
|
||||||
size 13081
|
size 13214
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
"Name": "Flax",
|
"Name": "Flax",
|
||||||
"Version": {
|
"Version": {
|
||||||
"Major": 1,
|
"Major": 1,
|
||||||
"Minor": 12,
|
"Minor": 11,
|
||||||
"Revision": 0,
|
"Revision": 0,
|
||||||
"Build": 6905
|
"Build": 6805
|
||||||
},
|
},
|
||||||
"Company": "Flax",
|
"Company": "Flax",
|
||||||
"Copyright": "Copyright (c) 2012-2026 Wojciech Figat. All rights reserved.",
|
"Copyright": "Copyright (c) 2012-2025 Wojciech Figat. All rights reserved.",
|
||||||
"GameTarget": "FlaxGame",
|
"GameTarget": "FlaxGame",
|
||||||
"EditorTarget": "FlaxEditor",
|
"EditorTarget": "FlaxEditor",
|
||||||
"Configuration": {
|
"Configuration": {
|
||||||
|
|||||||
@@ -188,7 +188,7 @@
|
|||||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
||||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_CASE_STATEMENT_ON_SAME_LINE/@EntryValue">ALWAYS</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_CASE_STATEMENT_STYLE/@EntryValue">ON_SINGLE_LINE</s:String>
|
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_CASE_STATEMENT_STYLE/@EntryValue">ON_SINGLE_LINE</s:String>
|
||||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ if errorlevel 1 goto BuildToolFailed
|
|||||||
|
|
||||||
:: Build bindings for all editor configurations
|
:: Build bindings for all editor configurations
|
||||||
echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor,FlaxGame
|
||||||
|
|
||||||
popd
|
popd
|
||||||
echo Done!
|
echo Done!
|
||||||
|
|||||||
@@ -187,11 +187,6 @@ namespace FlaxEditor.Content.Import
|
|||||||
// Glossiness, metalness, ambient occlusion, displacement, height, cavity or specular
|
// Glossiness, metalness, ambient occlusion, displacement, height, cavity or specular
|
||||||
_settings.Settings.Type = TextureFormatType.GrayScale;
|
_settings.Settings.Type = TextureFormatType.GrayScale;
|
||||||
}
|
}
|
||||||
else if (_settings.Settings.Type == TextureFormatType.ColorRGB)
|
|
||||||
{
|
|
||||||
// Blind guess that common color texture is sRGB
|
|
||||||
_settings.Settings.sRGB = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to restore target asset texture import options (useful for fast reimport)
|
// Try to restore target asset texture import options (useful for fast reimport)
|
||||||
Editor.TryRestoreImportOptions(ref _settings.Settings, ResultUrl);
|
Editor.TryRestoreImportOptions(ref _settings.Settings, ResultUrl);
|
||||||
|
|||||||
@@ -749,7 +749,7 @@ namespace FlaxEditor.Content
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw short name
|
// Draw short name
|
||||||
Render2D.PushClip(ref textRect);
|
Render2D.PushClip(textRect);
|
||||||
var scale = 0.95f * view.ViewScale;
|
var scale = 0.95f * view.ViewScale;
|
||||||
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, scale);
|
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, scale);
|
||||||
Render2D.PopClip();
|
Render2D.PopClip();
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ namespace FlaxEditor.Content.Thumbnails
|
|||||||
// Create render task but disabled for now
|
// Create render task but disabled for now
|
||||||
_output = GPUDevice.Instance.CreateTexture("ThumbnailsOutput");
|
_output = GPUDevice.Instance.CreateTexture("ThumbnailsOutput");
|
||||||
var desc = GPUTextureDescription.New2D(PreviewsCache.AssetIconSize, PreviewsCache.AssetIconSize, PreviewsCache.AssetIconsAtlasFormat);
|
var desc = GPUTextureDescription.New2D(PreviewsCache.AssetIconSize, PreviewsCache.AssetIconSize, PreviewsCache.AssetIconsAtlasFormat);
|
||||||
_output.Init(ref desc);
|
_output.Init(desc);
|
||||||
_task = Object.New<RenderTask>();
|
_task = Object.New<RenderTask>();
|
||||||
_task.Order = 50; // Render this task later
|
_task.Order = 50; // Render this task later
|
||||||
_task.Enabled = false;
|
_task.Enabled = false;
|
||||||
|
|||||||
@@ -141,11 +141,6 @@ API_ENUM() enum class BuildPlatform
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
|
API_ENUM(Attributes="EditorDisplay(null, \"Windows ARM64\")")
|
||||||
WindowsARM64 = 15,
|
WindowsARM64 = 15,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Web
|
|
||||||
/// </summary>
|
|
||||||
Web = 16,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -193,11 +188,6 @@ enum class DotNetAOTModes
|
|||||||
/// Use Mono AOT to cross-compile all used C# assemblies into native platform static libraries which can be linked into a single shared library.
|
/// Use Mono AOT to cross-compile all used C# assemblies into native platform static libraries which can be linked into a single shared library.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MonoAOTStatic,
|
MonoAOTStatic,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Target platform doesn't support .NET or it has been disabled.
|
|
||||||
/// </summary>
|
|
||||||
NoDotnet,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform);
|
extern FLAXENGINE_API const Char* ToString(const BuildPlatform platform);
|
||||||
|
|||||||
@@ -69,10 +69,6 @@
|
|||||||
#include "Platform/iOS/iOSPlatformTools.h"
|
#include "Platform/iOS/iOSPlatformTools.h"
|
||||||
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
|
#include "Engine/Platform/iOS/iOSPlatformSettings.h"
|
||||||
#endif
|
#endif
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
#include "Platform/Web/WebPlatformTools.h"
|
|
||||||
#include "Engine/Platform/Web/WebPlatformSettings.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace GameCookerImpl
|
namespace GameCookerImpl
|
||||||
{
|
{
|
||||||
@@ -155,8 +151,6 @@ const Char* ToString(const BuildPlatform platform)
|
|||||||
return TEXT("iOS ARM64");
|
return TEXT("iOS ARM64");
|
||||||
case BuildPlatform::WindowsARM64:
|
case BuildPlatform::WindowsARM64:
|
||||||
return TEXT("Windows ARM64");
|
return TEXT("Windows ARM64");
|
||||||
case BuildPlatform::Web:
|
|
||||||
return TEXT("Web");
|
|
||||||
default:
|
default:
|
||||||
return TEXT("");
|
return TEXT("");
|
||||||
}
|
}
|
||||||
@@ -189,8 +183,6 @@ const Char* ToString(const DotNetAOTModes mode)
|
|||||||
return TEXT("MonoAOTDynamic");
|
return TEXT("MonoAOTDynamic");
|
||||||
case DotNetAOTModes::MonoAOTStatic:
|
case DotNetAOTModes::MonoAOTStatic:
|
||||||
return TEXT("MonoAOTStatic");
|
return TEXT("MonoAOTStatic");
|
||||||
case DotNetAOTModes::NoDotnet:
|
|
||||||
return TEXT("NoDotnet");
|
|
||||||
default:
|
default:
|
||||||
return TEXT("");
|
return TEXT("");
|
||||||
}
|
}
|
||||||
@@ -315,10 +307,6 @@ void CookingData::GetBuildPlatformName(const Char*& platform, const Char*& archi
|
|||||||
platform = TEXT("Windows");
|
platform = TEXT("Windows");
|
||||||
architecture = TEXT("ARM64");
|
architecture = TEXT("ARM64");
|
||||||
break;
|
break;
|
||||||
case BuildPlatform::Web:
|
|
||||||
platform = TEXT("Web");
|
|
||||||
architecture = TEXT("x86");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
LOG(Fatal, "Unknown or unsupported build platform.");
|
LOG(Fatal, "Unknown or unsupported build platform.");
|
||||||
}
|
}
|
||||||
@@ -473,11 +461,6 @@ PlatformTools* GameCooker::GetTools(BuildPlatform platform)
|
|||||||
case BuildPlatform::iOSARM64:
|
case BuildPlatform::iOSARM64:
|
||||||
result = New<iOSPlatformTools>();
|
result = New<iOSPlatformTools>();
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
case BuildPlatform::Web:
|
|
||||||
result = New<WebPlatformTools>();
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
Tools.Add(platform, result);
|
Tools.Add(platform, result);
|
||||||
@@ -621,9 +604,6 @@ void GameCooker::GetCurrentPlatform(PlatformType& platform, BuildPlatform& build
|
|||||||
case PlatformType::iOS:
|
case PlatformType::iOS:
|
||||||
buildPlatform = BuildPlatform::iOSARM64;
|
buildPlatform = BuildPlatform::iOSARM64;
|
||||||
break;
|
break;
|
||||||
case PlatformType::Web:
|
|
||||||
buildPlatform = BuildPlatform::Web;
|
|
||||||
break;
|
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ namespace FlaxEditor
|
|||||||
case BuildPlatform.MacOSARM64:
|
case BuildPlatform.MacOSARM64:
|
||||||
case BuildPlatform.MacOSx64: return PlatformType.Mac;
|
case BuildPlatform.MacOSx64: return PlatformType.Mac;
|
||||||
case BuildPlatform.iOSARM64: return PlatformType.iOS;
|
case BuildPlatform.iOSARM64: return PlatformType.iOS;
|
||||||
case BuildPlatform.Web: return PlatformType.Web;
|
|
||||||
default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null);
|
default: throw new ArgumentOutOfRangeException(nameof(buildPlatform), buildPlatform, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,7 +138,6 @@ Array<byte> AndroidPlatformTools::SaveCache(CookingData& data, IBuildCache* cach
|
|||||||
result.Add((const byte*)&platformCache, sizeof(platformCache));
|
result.Add((const byte*)&platformCache, sizeof(platformCache));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidPlatformTools::OnBuildStarted(CookingData& data)
|
void AndroidPlatformTools::OnBuildStarted(CookingData& data)
|
||||||
{
|
{
|
||||||
// Adjust the cooking output folder to be located inside the Gradle assets directory
|
// Adjust the cooking output folder to be located inside the Gradle assets directory
|
||||||
@@ -412,6 +411,7 @@ bool AndroidPlatformTools::OnPostProcess(CookingData& data)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
|
LOG(Info, "Output Android APK application package: {0} (size: {1} MB)", outputApk, FileSystem::GetFileSize(outputApk) / 1024 / 1024);
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,157 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
|
|
||||||
#include "WebPlatformTools.h"
|
|
||||||
#include "Engine/Platform/File.h"
|
|
||||||
#include "Engine/Platform/FileSystem.h"
|
|
||||||
#include "Engine/Platform/CreateProcessSettings.h"
|
|
||||||
#include "Engine/Platform/Web/WebPlatformSettings.h"
|
|
||||||
#include "Engine/Core/Config/GameSettings.h"
|
|
||||||
#include "Engine/Core/Config/BuildSettings.h"
|
|
||||||
#include "Engine/Content/Content.h"
|
|
||||||
#include "Engine/Content/JsonAsset.h"
|
|
||||||
#include "Engine/Graphics/PixelFormatExtensions.h"
|
|
||||||
#include "Editor/Cooker/GameCooker.h"
|
|
||||||
|
|
||||||
IMPLEMENT_SETTINGS_GETTER(WebPlatformSettings, WebPlatform);
|
|
||||||
|
|
||||||
const Char* WebPlatformTools::GetDisplayName() const
|
|
||||||
{
|
|
||||||
return TEXT("Web");
|
|
||||||
}
|
|
||||||
|
|
||||||
const Char* WebPlatformTools::GetName() const
|
|
||||||
{
|
|
||||||
return TEXT("Web");
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformType WebPlatformTools::GetPlatform() const
|
|
||||||
{
|
|
||||||
return PlatformType::Web;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArchitectureType WebPlatformTools::GetArchitecture() const
|
|
||||||
{
|
|
||||||
return ArchitectureType::x86;
|
|
||||||
}
|
|
||||||
|
|
||||||
DotNetAOTModes WebPlatformTools::UseAOT() const
|
|
||||||
{
|
|
||||||
return DotNetAOTModes::NoDotnet;
|
|
||||||
}
|
|
||||||
|
|
||||||
PixelFormat WebPlatformTools::GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format)
|
|
||||||
{
|
|
||||||
// TODO: texture compression for Web (eg. ASTC for mobile and BC for others?)
|
|
||||||
return PixelFormatExtensions::FindUncompressedFormat(format);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatformTools::IsNativeCodeFile(CookingData& data, const String& file)
|
|
||||||
{
|
|
||||||
String extension = FileSystem::GetExtension(file);
|
|
||||||
return extension.IsEmpty() || extension == TEXT("html") || extension == TEXT("js") || extension == TEXT("wasm");
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebPlatformTools::OnBuildStarted(CookingData& data)
|
|
||||||
{
|
|
||||||
// Adjust the cooking output folder for the data files so file_packager tool can build the and output final data inside the cooker output folder
|
|
||||||
data.DataOutputPath = data.CacheDirectory / TEXT("Files");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WebPlatformTools::OnPostProcess(CookingData& data)
|
|
||||||
{
|
|
||||||
const auto gameSettings = GameSettings::Get();
|
|
||||||
const auto platformSettings = WebPlatformSettings::Get();
|
|
||||||
const auto platformDataPath = data.GetPlatformBinariesRoot();
|
|
||||||
|
|
||||||
// Get name of the output binary (JavaScript and WebAssembly files match)
|
|
||||||
String gameJs;
|
|
||||||
{
|
|
||||||
Array<String> files;
|
|
||||||
FileSystem::DirectoryGetFiles(files, data.OriginalOutputPath, TEXT("*"), DirectorySearchOption::TopDirectoryOnly);
|
|
||||||
for (String& file : files)
|
|
||||||
{
|
|
||||||
if (file.EndsWith(TEXT(".js")))
|
|
||||||
{
|
|
||||||
String outputWasm = String(StringUtils::GetPathWithoutExtension(file)) + TEXT(".wasm");
|
|
||||||
if (files.Contains(outputWasm))
|
|
||||||
{
|
|
||||||
gameJs = file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (gameJs.IsEmpty())
|
|
||||||
{
|
|
||||||
data.Error(TEXT("Failed to find the main JavaScript for the output game"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pack data files into a single file using Emscripten's file_packager tool
|
|
||||||
{
|
|
||||||
CreateProcessSettings procSettings;
|
|
||||||
String emscriptenSdk = TEXT("EMSDK");
|
|
||||||
Platform::GetEnvironmentVariable(emscriptenSdk, emscriptenSdk);
|
|
||||||
procSettings.FileName = emscriptenSdk / TEXT("upstream/emscripten/tools/file_packager");
|
|
||||||
#if PLATFORM_WIN32
|
|
||||||
procSettings.FileName += TEXT(".bat");
|
|
||||||
#endif
|
|
||||||
procSettings.Arguments = String::Format(TEXT("files.data --preload \"{}@/\" --lz4 --js-output=files.js"), data.DataOutputPath);
|
|
||||||
procSettings.WorkingDirectory = data.OriginalOutputPath;
|
|
||||||
const int32 result = Platform::CreateProcess(procSettings);
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
if (!FileSystem::FileExists(procSettings.FileName))
|
|
||||||
data.Error(TEXT("Missing file_packager.bat. Ensure Emscripten SDK installation is valid and 'EMSDK' environment variable points to it."));
|
|
||||||
data.Error(String::Format(TEXT("Failed to package project files (result code: {0}). See log for more info."), result));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: customizable HTML templates
|
|
||||||
|
|
||||||
// Insert packaged file system with game data
|
|
||||||
{
|
|
||||||
String gameJsText;
|
|
||||||
if (File::ReadAllText(gameJs, gameJsText))
|
|
||||||
{
|
|
||||||
data.Error(String::Format(TEXT("Failed to load file '{}'"), gameJs));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const String filesIncludeBegin = TEXT("// include: files.js");
|
|
||||||
const String filesIncludeEnd = TEXT("// end include: files.js");
|
|
||||||
if (!gameJsText.Contains(filesIncludeBegin))
|
|
||||||
{
|
|
||||||
// Insert generated files.js into the main game file after the minimum_runtime_check.js include
|
|
||||||
String fileJsText;
|
|
||||||
String fileJs = data.OriginalOutputPath / TEXT("files.js");
|
|
||||||
if (File::ReadAllText(fileJs, fileJsText))
|
|
||||||
{
|
|
||||||
data.Error(String::Format(TEXT("Failed to load file '{}'"), fileJs));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
const String insertPrefixLocation = TEXT("// end include: minimum_runtime_check.js");
|
|
||||||
int32 location = gameJsText.Find(insertPrefixLocation);
|
|
||||||
CHECK_RETURN(location != -1, true);
|
|
||||||
location += insertPrefixLocation.Length() + 1;
|
|
||||||
fileJsText = filesIncludeBegin + TEXT("\n") + fileJsText + TEXT("\n") + filesIncludeEnd + TEXT("\n");
|
|
||||||
gameJsText.Insert(location, fileJsText);
|
|
||||||
File::WriteAllText(gameJs, gameJsText, Encoding::UTF8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto buildSettings = BuildSettings::Get();
|
|
||||||
if (buildSettings->SkipPackaging)
|
|
||||||
return false;
|
|
||||||
GameCooker::PackageFiles();
|
|
||||||
|
|
||||||
// TODO: minify/compress output JS files (in Release builds)
|
|
||||||
|
|
||||||
LOG(Info, "Output website size: {0} MB", FileSystem::GetDirectorySize(data.OriginalOutputPath) / 1024 / 1024);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
|
|
||||||
#include "../../PlatformTools.h"
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Web platform support tools.
|
|
||||||
/// </summary>
|
|
||||||
class WebPlatformTools : public PlatformTools
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// [PlatformTools]
|
|
||||||
const Char* GetDisplayName() const override;
|
|
||||||
const Char* GetName() const override;
|
|
||||||
PlatformType GetPlatform() const override;
|
|
||||||
ArchitectureType GetArchitecture() const override;
|
|
||||||
DotNetAOTModes UseAOT() const override;
|
|
||||||
PixelFormat GetTextureFormat(CookingData& data, TextureBase* texture, PixelFormat format) override;
|
|
||||||
bool IsNativeCodeFile(CookingData& data, const String& file) override;
|
|
||||||
void OnBuildStarted(CookingData& data) override;
|
|
||||||
bool OnPostProcess(CookingData& data) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -572,14 +572,6 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
|
|||||||
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
|
COMPILE_PROFILE(Vulkan_SM5, SHADER_FILE_CHUNK_INTERNAL_VULKAN_SM5_CACHE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if PLATFORM_TOOLS_WEB
|
|
||||||
case BuildPlatform::Web:
|
|
||||||
{
|
|
||||||
const char* platformDefineName = "PLATFORM_WEB";
|
|
||||||
// TODO: compile shaders for WebGPU
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,23 +39,17 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
}
|
}
|
||||||
String dstDotnet = data.DataOutputPath / TEXT("Dotnet");
|
String dstDotnet = data.DataOutputPath / TEXT("Dotnet");
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
const bool usAOT = aotMode != DotNetAOTModes::None && aotMode != DotNetAOTModes::NoDotnet;
|
const bool usAOT = aotMode != DotNetAOTModes::None;
|
||||||
if (usAOT)
|
if (usAOT)
|
||||||
{
|
{
|
||||||
// Deploy Dotnet files into intermediate cooking directory for AOT
|
// Deploy Dotnet files into intermediate cooking directory for AOT
|
||||||
FileSystem::DeleteDirectory(dstDotnet);
|
FileSystem::DeleteDirectory(dstDotnet);
|
||||||
dstDotnet = data.ManagedCodeOutputPath;
|
dstDotnet = data.ManagedCodeOutputPath;
|
||||||
}
|
}
|
||||||
if (aotMode == DotNetAOTModes::NoDotnet)
|
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
||||||
{
|
|
||||||
// No .NET
|
|
||||||
FileSystem::DeleteDirectory(dstDotnet);
|
|
||||||
}
|
|
||||||
else if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
|
||||||
{
|
{
|
||||||
// Use system-installed .NET Runtime
|
// Use system-installed .NET Runtime
|
||||||
FileSystem::DeleteDirectory(dstDotnet);
|
FileSystem::DeleteDirectory(dstDotnet);
|
||||||
LOG(Info, "Not using .NET Runtime");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,9 +12,7 @@
|
|||||||
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
||||||
{
|
{
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
if (aotMode == DotNetAOTModes::None ||
|
if (aotMode == DotNetAOTModes::None || EnumHasAllFlags(data.Options, BuildOptions::NoCook))
|
||||||
aotMode == DotNetAOTModes::NoDotnet ||
|
|
||||||
EnumHasAllFlags(data.Options, BuildOptions::NoCook))
|
|
||||||
return;
|
return;
|
||||||
const auto& buildSettings = *BuildSettings::Get();
|
const auto& buildSettings = *BuildSettings::Get();
|
||||||
|
|
||||||
@@ -51,8 +49,7 @@ void PrecompileAssembliesStep::OnBuildStarted(CookingData& data)
|
|||||||
bool PrecompileAssembliesStep::Perform(CookingData& data)
|
bool PrecompileAssembliesStep::Perform(CookingData& data)
|
||||||
{
|
{
|
||||||
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
const DotNetAOTModes aotMode = data.Tools->UseAOT();
|
||||||
if (aotMode == DotNetAOTModes::None ||
|
if (aotMode == DotNetAOTModes::None)
|
||||||
aotMode == DotNetAOTModes::NoDotnet)
|
|
||||||
return false;
|
return false;
|
||||||
const auto& buildSettings = *BuildSettings::Get();
|
const auto& buildSettings = *BuildSettings::Get();
|
||||||
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
if (buildSettings.SkipDotnetPackaging && data.Tools->UseSystemDotnet())
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
return new GenericEditor();
|
return new GenericEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "CustomEditorsUtilInternal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "CustomEditorsUtilInternal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
[return: MarshalUsing(typeof(SystemTypeMarshaller))]
|
[return: MarshalUsing(typeof(SystemTypeMarshaller))]
|
||||||
internal static partial Type Internal_GetCustomEditor([MarshalUsing(typeof(SystemTypeMarshaller))] Type targetType);
|
internal static partial Type Internal_GetCustomEditor([MarshalUsing(typeof(SystemTypeMarshaller))] Type targetType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,14 +60,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
if (prefab && !prefab.WaitForLoaded())
|
if (prefab && !prefab.WaitForLoaded())
|
||||||
{
|
{
|
||||||
var prefabObjectId = actor.PrefabObjectID;
|
var prefabObjectId = actor.PrefabObjectID;
|
||||||
var prefabInstance = prefab.GetDefaultInstance(ref prefabObjectId);
|
var prefabInstance = prefab.GetDefaultInstance(prefabObjectId);
|
||||||
if (prefabInstance != null)
|
if (prefabInstance != null)
|
||||||
{
|
{
|
||||||
// Use default prefab instance as a reference for the editor
|
// Use default prefab instance as a reference for the editor
|
||||||
Values.SetReferenceValue(prefabInstance);
|
Values.SetReferenceValue(prefabInstance);
|
||||||
|
|
||||||
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
|
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
|
||||||
prefab.GetNestedObject(ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
|
prefab.GetNestedObject(prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
|
||||||
var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId);
|
var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId);
|
||||||
var panel = layout.UniformGrid();
|
var panel = layout.UniformGrid();
|
||||||
panel.CustomControl.Height = 20.0f;
|
panel.CustomControl.Height = 20.0f;
|
||||||
@@ -207,7 +207,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
{
|
{
|
||||||
var actor = (Actor)Values[0];
|
var actor = (Actor)Values[0];
|
||||||
var prefabObjectId = actor.PrefabObjectID;
|
var prefabObjectId = actor.PrefabObjectID;
|
||||||
var prefabInstance = prefab.GetDefaultInstance(ref prefabObjectId);
|
var prefabInstance = prefab.GetDefaultInstance(prefabObjectId);
|
||||||
if (prefabInstance != null)
|
if (prefabInstance != null)
|
||||||
{
|
{
|
||||||
Values.SetReferenceValue(prefabInstance);
|
Values.SetReferenceValue(prefabInstance);
|
||||||
@@ -525,7 +525,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
var restored = actor.AddScript(removed.PrefabObject.GetType());
|
var restored = actor.AddScript(removed.PrefabObject.GetType());
|
||||||
var prefabId = actor.PrefabID;
|
var prefabId = actor.PrefabID;
|
||||||
var prefabObjectId = restored.PrefabObjectID;
|
var prefabObjectId = restored.PrefabObjectID;
|
||||||
Script.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), ref prefabId, ref prefabObjectId);
|
Script.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), prefabId, prefabObjectId);
|
||||||
string data = JsonSerializer.Serialize(removed.PrefabObject);
|
string data = JsonSerializer.Serialize(removed.PrefabObject);
|
||||||
JsonSerializer.Deserialize(restored, data);
|
JsonSerializer.Deserialize(restored, data);
|
||||||
|
|
||||||
@@ -547,7 +547,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
string data = JsonSerializer.Serialize(removedActor.PrefabObject);
|
string data = JsonSerializer.Serialize(removedActor.PrefabObject);
|
||||||
JsonSerializer.Deserialize(restored, data);
|
JsonSerializer.Deserialize(restored, data);
|
||||||
Presenter.Owner.SceneContext.Spawn(restored, parentActor, removedActor.OrderInParent);
|
Presenter.Owner.SceneContext.Spawn(restored, parentActor, removedActor.OrderInParent);
|
||||||
Actor.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), ref prefabId, ref prefabObjectId);
|
Actor.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), prefabId, prefabObjectId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
|
|
||||||
if (Values.HasDifferentTypes == false)
|
if (Values.HasDifferentTypes == false)
|
||||||
{
|
{
|
||||||
var group = layout.Group("Probe");
|
var group = layout.Group("Bake");
|
||||||
group.Panel.ItemsMargin = new Margin(Utilities.Constants.UIMargin * 2);
|
group.Panel.ItemsMargin = new Margin(Utilities.Constants.UIMargin * 2);
|
||||||
_bake = group.Button("Bake").Button;
|
_bake = group.Button("Bake").Button;
|
||||||
_bake.Clicked += BakeButtonClicked;
|
_bake.Clicked += BakeButtonClicked;
|
||||||
var view = group.Button("View", "Opens the probe texture viewer");
|
|
||||||
view.Button.Clicked += OnViewButtonClicked;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,14 +50,5 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnViewButtonClicked()
|
|
||||||
{
|
|
||||||
foreach (var value in Values)
|
|
||||||
{
|
|
||||||
if (value is EnvironmentProbe probe && probe.ProbeAsset)
|
|
||||||
Editor.Instance.ContentEditing.Open(probe.ProbeAsset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
filesCount += files.Length;
|
filesCount += files.Length;
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
FindNewKeysCpp(file, newKeys, allKeys);
|
FindNewKeysCpp(file, newKeys, allKeys);
|
||||||
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.hpp", SearchOption.AllDirectories)).ToArray();
|
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.hpp", SearchOption.AllDirectories)).ToArray();;
|
||||||
filesCount += files.Length;
|
filesCount += files.Length;
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
FindNewKeysCpp(file, newKeys, allKeys);
|
FindNewKeysCpp(file, newKeys, allKeys);
|
||||||
|
|||||||
@@ -164,11 +164,11 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
|
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
|
||||||
|
|
||||||
// Deselect
|
// Deselect
|
||||||
if (isSelected && button1Rect.Contains(ref location))
|
if (isSelected && button1Rect.Contains(location))
|
||||||
Value = new ModelInstanceActor.MeshReference { Actor = null, LODIndex = -1, MeshIndex = -1 };
|
Value = new ModelInstanceActor.MeshReference { Actor = null, LODIndex = -1, MeshIndex = -1 };
|
||||||
|
|
||||||
// Picker dropdown menu
|
// Picker dropdown menu
|
||||||
if ((isSelected ? button2Rect : button1Rect).Contains(ref location))
|
if ((isSelected ? button2Rect : button1Rect).Contains(location))
|
||||||
ShowDropDownMenu();
|
ShowDropDownMenu();
|
||||||
|
|
||||||
return base.OnMouseUp(location, button);
|
return base.OnMouseUp(location, button);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class ModelPrefabEditor : GenericEditor
|
|||||||
if (prefab)
|
if (prefab)
|
||||||
{
|
{
|
||||||
var prefabObjectId = modelPrefab.PrefabObjectID;
|
var prefabObjectId = modelPrefab.PrefabObjectID;
|
||||||
var prefabObject = prefab.GetDefaultInstance(ref prefabObjectId);
|
var prefabObject = prefab.GetDefaultInstance(prefabObjectId);
|
||||||
if (prefabObject.PrefabID == _prefabId)
|
if (prefabObject.PrefabID == _prefabId)
|
||||||
break;
|
break;
|
||||||
_prefabId = prefabObject.PrefabID;
|
_prefabId = prefabObject.PrefabID;
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
using FlaxEngine;
|
|
||||||
|
|
||||||
namespace FlaxEditor.CustomEditors.Dedicated
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Custom editor for <see cref="NavMeshBoundsVolume"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="ActorEditor" />
|
|
||||||
[CustomEditor(typeof(NavMeshBoundsVolume)), DefaultEditor]
|
|
||||||
internal class NavMeshBoundsVolumeEditor : ActorEditor
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
|
||||||
{
|
|
||||||
base.Initialize(layout);
|
|
||||||
|
|
||||||
if (Values.HasDifferentTypes == false)
|
|
||||||
{
|
|
||||||
var button = layout.Button("Build");
|
|
||||||
button.Button.Clicked += OnBuildClicked;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnBuildClicked()
|
|
||||||
{
|
|
||||||
foreach (var value in Values)
|
|
||||||
{
|
|
||||||
if (value is NavMeshBoundsVolume volume)
|
|
||||||
{
|
|
||||||
Navigation.BuildNavMesh(volume.Box, volume.Scene);
|
|
||||||
Editor.Instance.Scene.MarkSceneEdited(volume.Scene);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) Wojciech Figat. All rights reserved.
|
// Copyright (c) Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection.Emit;
|
||||||
using FlaxEditor.CustomEditors.GUI;
|
using FlaxEditor.CustomEditors.GUI;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
|||||||
@@ -909,8 +909,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
settingsButton.Tag = script;
|
settingsButton.Tag = script;
|
||||||
settingsButton.Clicked += OnSettingsButtonClicked;
|
settingsButton.Clicked += OnSettingsButtonClicked;
|
||||||
|
|
||||||
// Adjust margin to not overlap with other ui elements in the header
|
group.Panel.HeaderTextMargin = new Margin(scriptDrag.Right - 12, 15, 2, 2);
|
||||||
group.Panel.HeaderTextMargin = group.Panel.HeaderTextMargin with { Left = scriptDrag.Right - 12, Right = settingsButton.Width + Utilities.Constants.UIMargin };
|
|
||||||
group.Object(values, editor);
|
group.Object(values, editor);
|
||||||
// Remove drop down arrows and containment lines if no objects in the group
|
// Remove drop down arrows and containment lines if no objects in the group
|
||||||
if (group.Children.Count == 0)
|
if (group.Children.Count == 0)
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
if (DropdownRect.Contains(ref location))
|
if (DropdownRect.Contains(location))
|
||||||
{
|
{
|
||||||
Focus();
|
Focus();
|
||||||
ShowPicker();
|
ShowPicker();
|
||||||
@@ -206,7 +206,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
base.OnMouseMove(location);
|
base.OnMouseMove(location);
|
||||||
|
|
||||||
if (DropdownRect.Contains(ref location))
|
if (DropdownRect.Contains(location))
|
||||||
Cursor = CursorType.Default;
|
Cursor = CursorType.Default;
|
||||||
else
|
else
|
||||||
Cursor = CursorType.IBeam;
|
Cursor = CursorType.IBeam;
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
|
if (button == MouseButton.Left && _arrangeButtonRect.Contains(location))
|
||||||
{
|
{
|
||||||
_arrangeButtonInUse = true;
|
_arrangeButtonInUse = true;
|
||||||
Focus();
|
Focus();
|
||||||
@@ -371,7 +371,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
|
if (button == MouseButton.Left && _arrangeButtonRect.Contains(location))
|
||||||
{
|
{
|
||||||
_arrangeButtonInUse = true;
|
_arrangeButtonInUse = true;
|
||||||
Focus();
|
Focus();
|
||||||
@@ -450,7 +450,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
protected bool NotNullItems;
|
protected bool NotNullItems;
|
||||||
|
|
||||||
private IntValueBox _sizeBox;
|
private IntValueBox _sizeBox;
|
||||||
private Label _label;
|
|
||||||
private Color _background;
|
private Color _background;
|
||||||
private int _elementsCount, _minCount, _maxCount;
|
private int _elementsCount, _minCount, _maxCount;
|
||||||
private bool _readOnly;
|
private bool _readOnly;
|
||||||
@@ -567,7 +566,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
Parent = dropPanel,
|
Parent = dropPanel,
|
||||||
};
|
};
|
||||||
|
|
||||||
_label = new Label
|
var label = new Label
|
||||||
{
|
{
|
||||||
Text = "Size",
|
Text = "Size",
|
||||||
AnchorPreset = AnchorPresets.TopRight,
|
AnchorPreset = AnchorPresets.TopRight,
|
||||||
@@ -593,12 +592,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
panel.Panel.Offsets = new Margin(7, 7, 0, 0);
|
panel.Panel.Offsets = new Margin(7, 7, 0, 0);
|
||||||
panel.Panel.BackgroundColor = _background;
|
panel.Panel.BackgroundColor = _background;
|
||||||
var elementType = ElementType;
|
var elementType = ElementType;
|
||||||
var bindingAttr = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public;
|
|
||||||
bool single = elementType.IsPrimitive ||
|
bool single = elementType.IsPrimitive ||
|
||||||
elementType.Equals(new ScriptType(typeof(string))) ||
|
elementType.Equals(new ScriptType(typeof(string))) ||
|
||||||
elementType.IsEnum ||
|
elementType.IsEnum ||
|
||||||
(elementType.GetFields(bindingAttr).Length == 1 && elementType.GetProperties(bindingAttr).Length == 0) ||
|
(elementType.GetFields().Length == 1 && elementType.GetProperties().Length == 0) ||
|
||||||
(elementType.GetProperties(bindingAttr).Length == 1 && elementType.GetFields(bindingAttr).Length == 0) ||
|
(elementType.GetProperties().Length == 1 && elementType.GetFields().Length == 0) ||
|
||||||
elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
|
elementType.Equals(new ScriptType(typeof(JsonAsset))) ||
|
||||||
elementType.Equals(new ScriptType(typeof(SettingsBase)));
|
elementType.Equals(new ScriptType(typeof(SettingsBase)));
|
||||||
if (_cachedDropPanels == null)
|
if (_cachedDropPanels == null)
|
||||||
@@ -674,10 +672,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
Resize(Count + 1);
|
Resize(Count + 1);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout.ContainerControl.SizeChanged += OnLayoutSizeChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSetupContextMenu(ContextMenu menu, DropPanel panel)
|
private void OnSetupContextMenu(ContextMenu menu, DropPanel panel)
|
||||||
{
|
{
|
||||||
if (menu.Items.Any(x => x is ContextMenuButton b && b.Text.Equals("Open All", StringComparison.Ordinal)))
|
if (menu.Items.Any(x => x is ContextMenuButton b && b.Text.Equals("Open All", StringComparison.Ordinal)))
|
||||||
@@ -700,24 +696,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLayoutSizeChanged(Control control)
|
|
||||||
{
|
|
||||||
if (Layout.ContainerControl is DropPanel dropPanel)
|
|
||||||
{
|
|
||||||
// Hide "Size" text when array editor title overlaps
|
|
||||||
var headerTextSize = dropPanel.HeaderTextFont.GetFont().MeasureText(dropPanel.HeaderText);
|
|
||||||
if (headerTextSize.X + DropPanel.DropDownIconSize >= _label.Left)
|
|
||||||
_label.TextColor = _label.TextColorHighlighted = Color.Transparent;
|
|
||||||
else
|
|
||||||
_label.TextColor = _label.TextColorHighlighted = FlaxEngine.GUI.Style.Current.Foreground;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Deinitialize()
|
protected override void Deinitialize()
|
||||||
{
|
{
|
||||||
_sizeBox = null;
|
_sizeBox = null;
|
||||||
Layout.ContainerControl.SizeChanged -= OnLayoutSizeChanged;
|
|
||||||
|
|
||||||
base.Deinitialize();
|
base.Deinitialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -321,11 +321,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
|
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
|
||||||
|
|
||||||
// Deselect
|
// Deselect
|
||||||
if (_value != null && button1Rect.Contains(ref location))
|
if (_value != null && button1Rect.Contains(location))
|
||||||
Value = null;
|
Value = null;
|
||||||
|
|
||||||
// Picker dropdown menu
|
// Picker dropdown menu
|
||||||
if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(ref location))
|
if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(location))
|
||||||
{
|
{
|
||||||
ShowDropDownMenu();
|
ShowDropDownMenu();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
/// <returns>The items.</returns>
|
/// <returns>The items.</returns>
|
||||||
protected virtual List<ItemInfo> GetItemsForType(ScriptType type)
|
protected virtual List<ItemInfo> GetItemsForType(ScriptType type)
|
||||||
{
|
{
|
||||||
return GetItemsForType(type, type.IsClass, true);
|
return GetItemsForType(type, type.IsClass, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -273,10 +273,14 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var attributes = p.GetAttributes(true);
|
var attributes = p.GetAttributes(true);
|
||||||
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
|
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
|
||||||
|
|
||||||
// Skip properties without getter or setter
|
// Skip properties without getter
|
||||||
if (!p.HasGet || (!p.HasSet && !showInEditor && !usePropertiesWithoutSetter))
|
if (!p.HasGet || (!p.HasSet && !showInEditor && !usePropertiesWithoutSetter))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Skip getter-only properties declared in built-in types
|
||||||
|
if (!p.HasSet && usePropertiesWithoutSetter && p.Type.DeclaringType.Assembly == typeof(Editor).Assembly)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Skip hidden fields, handle special attributes
|
// Skip hidden fields, handle special attributes
|
||||||
if ((!p.IsPublic && !showInEditor) || attributes.Any(x => x is HideInEditorAttribute))
|
if ((!p.IsPublic && !showInEditor) || attributes.Any(x => x is HideInEditorAttribute))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -47,8 +47,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
return inputEvent;
|
return inputEvent;
|
||||||
if (Values[0] is string str)
|
if (Values[0] is string str)
|
||||||
return str;
|
return str;
|
||||||
if (Values.Type.Type == typeof(InputEvent))
|
|
||||||
return new InputEvent();
|
|
||||||
if (Values.Type.Type == typeof(string))
|
if (Values.Type.Type == typeof(string))
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -219,11 +219,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
|
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
|
||||||
|
|
||||||
// Deselect
|
// Deselect
|
||||||
if (_value && button1Rect.Contains(ref location) && _type == ScriptType.Null)
|
if (_value && button1Rect.Contains(location) && _type == ScriptType.Null)
|
||||||
Value = ScriptType.Null;
|
Value = ScriptType.Null;
|
||||||
|
|
||||||
// Picker dropdown menu
|
// Picker dropdown menu
|
||||||
if ((isSelected && _type == ScriptType.Null ? button2Rect : button1Rect).Contains(ref location))
|
if ((isSelected && _type == ScriptType.Null ? button2Rect : button1Rect).Contains(location))
|
||||||
ShowDropDownMenu();
|
ShowDropDownMenu();
|
||||||
|
|
||||||
return base.OnMouseUp(location, button);
|
return base.OnMouseUp(location, button);
|
||||||
|
|||||||
@@ -44,8 +44,7 @@ namespace FlaxEditor.CustomEditors.Elements
|
|||||||
{
|
{
|
||||||
var style = Style.Current;
|
var style = Style.Current;
|
||||||
var settingsButtonSize = Panel.HeaderHeight;
|
var settingsButtonSize = Panel.HeaderHeight;
|
||||||
Panel.HeaderTextMargin = Panel.HeaderTextMargin with { Right = settingsButtonSize + Utilities.Constants.UIMargin };
|
return new Image
|
||||||
; return new Image
|
|
||||||
{
|
{
|
||||||
TooltipText = "Settings",
|
TooltipText = "Settings",
|
||||||
AutoFocus = true,
|
AutoFocus = true,
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ public class Editor : EditorModule
|
|||||||
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Android", "PLATFORM_TOOLS_ANDROID");
|
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Android", "PLATFORM_TOOLS_ANDROID");
|
||||||
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "iOS", "PLATFORM_TOOLS_IOS");
|
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "iOS", "PLATFORM_TOOLS_IOS");
|
||||||
}
|
}
|
||||||
AddPlatformTools(options, platformToolsRoot, platformToolsRootExternal, "Web", "PLATFORM_TOOLS_WEB");
|
|
||||||
|
|
||||||
// Visual Studio integration
|
// Visual Studio integration
|
||||||
if (options.Platform.Target == TargetPlatform.Windows && Flax.Build.Platform.BuildTargetPlatform == TargetPlatform.Windows)
|
if (options.Platform.Target == TargetPlatform.Windows && Flax.Build.Platform.BuildTargetPlatform == TargetPlatform.Windows)
|
||||||
|
|||||||
@@ -526,6 +526,23 @@ int32 Editor::LoadProduct()
|
|||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the last opened project path
|
||||||
|
String localCachePath;
|
||||||
|
FileSystem::GetSpecialFolderPath(SpecialFolder::AppData, localCachePath);
|
||||||
|
String editorConfigPath = localCachePath / TEXT("Flax");
|
||||||
|
String lastProjectSettingPath = editorConfigPath / TEXT("LastProject.txt");
|
||||||
|
if (!FileSystem::DirectoryExists(editorConfigPath))
|
||||||
|
FileSystem::CreateDirectory(editorConfigPath);
|
||||||
|
String lastProjectPath;
|
||||||
|
if (FileSystem::FileExists(lastProjectSettingPath))
|
||||||
|
File::ReadAllText(lastProjectSettingPath, lastProjectPath);
|
||||||
|
if (!FileSystem::DirectoryExists(lastProjectPath))
|
||||||
|
lastProjectPath = String::Empty;
|
||||||
|
|
||||||
|
// Try to open the last project when requested
|
||||||
|
if (projectPath.IsEmpty() && CommandLine::Options.LastProject.IsTrue() && !lastProjectPath.IsEmpty())
|
||||||
|
projectPath = lastProjectPath;
|
||||||
|
|
||||||
// Missing project case
|
// Missing project case
|
||||||
if (projectPath.IsEmpty())
|
if (projectPath.IsEmpty())
|
||||||
{
|
{
|
||||||
@@ -541,7 +558,7 @@ int32 Editor::LoadProduct()
|
|||||||
Array<String> files;
|
Array<String> files;
|
||||||
if (FileSystem::ShowOpenFileDialog(
|
if (FileSystem::ShowOpenFileDialog(
|
||||||
nullptr,
|
nullptr,
|
||||||
StringView::Empty,
|
lastProjectPath,
|
||||||
TEXT("Project files (*.flaxproj)\0*.flaxproj\0All files (*.*)\0*.*\0"),
|
TEXT("Project files (*.flaxproj)\0*.flaxproj\0All files (*.*)\0*.*\0"),
|
||||||
false,
|
false,
|
||||||
TEXT("Select project to open in Editor"),
|
TEXT("Select project to open in Editor"),
|
||||||
@@ -625,6 +642,10 @@ int32 Editor::LoadProduct()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the last opened project path
|
||||||
|
if (lastProjectPath.Compare(Project->ProjectFolderPath) != 0)
|
||||||
|
File::WriteAllText(lastProjectSettingPath, Project->ProjectFolderPath, Encoding::UTF8);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ using FlaxEngine.Assertions;
|
|||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Interop;
|
using FlaxEngine.Interop;
|
||||||
using FlaxEngine.Json;
|
using FlaxEngine.Json;
|
||||||
using FlaxEngine.Utilities;
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
@@ -70,18 +69,18 @@ namespace FlaxEditor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this Editor is running a dev instance of the engine.
|
/// Gets a value indicating whether this Editor is running a dev instance of the engine.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsDevInstance", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsDevInstance")]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool IsDevInstance();
|
internal static partial bool IsDevInstance();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this Editor is running as official build (distributed via Flax services).
|
/// Gets a value indicating whether this Editor is running as official build (distributed via Flax services).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsOfficialBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsOfficialBuild")]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool IsOfficialBuild();
|
internal static partial bool IsOfficialBuild();
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsPlayMode")]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_IsPlayMode();
|
internal static partial bool Internal_IsPlayMode();
|
||||||
|
|
||||||
@@ -1057,7 +1056,7 @@ namespace FlaxEditor
|
|||||||
if (actor)
|
if (actor)
|
||||||
{
|
{
|
||||||
Internal_GetEditorBoxWithChildren(FlaxEngine.Object.GetUnmanagedPtr(actor), out var box);
|
Internal_GetEditorBoxWithChildren(FlaxEngine.Object.GetUnmanagedPtr(actor), out var box);
|
||||||
BoundingSphere.FromBox(ref box, out sphere);
|
BoundingSphere.FromBox(box, out sphere);
|
||||||
if (sphere == BoundingSphere.Empty)
|
if (sphere == BoundingSphere.Empty)
|
||||||
sphere = new BoundingSphere(actor.Position, sphere.Radius);
|
sphere = new BoundingSphere(actor.Position, sphere.Radius);
|
||||||
sphere.Radius = Math.Max(sphere.Radius, 15.0f);
|
sphere.Radius = Math.Max(sphere.Radius, 15.0f);
|
||||||
@@ -1371,7 +1370,7 @@ namespace FlaxEditor
|
|||||||
public void BuildCSG()
|
public void BuildCSG()
|
||||||
{
|
{
|
||||||
var scenes = Level.Scenes;
|
var scenes = Level.Scenes;
|
||||||
scenes.ForEach(x => x.BuildCSG(0));
|
scenes.ToList().ForEach(x => x.BuildCSG(0));
|
||||||
Scene.MarkSceneEdited(scenes);
|
Scene.MarkSceneEdited(scenes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1381,7 +1380,7 @@ namespace FlaxEditor
|
|||||||
public void BuildNavMesh()
|
public void BuildNavMesh()
|
||||||
{
|
{
|
||||||
var scenes = Level.Scenes;
|
var scenes = Level.Scenes;
|
||||||
Navigation.BuildNavMesh();
|
scenes.ToList().ForEach(x => Navigation.BuildNavMesh(x, 0));
|
||||||
Scene.MarkSceneEdited(scenes);
|
Scene.MarkSceneEdited(scenes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1648,96 +1647,103 @@ namespace FlaxEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ReadOutputLogs", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ReadOutputLogs", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
internal static partial int Internal_ReadOutputLogs([MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref string[] outMessages, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref byte[] outLogTypes, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref long[] outLogTimes, int outCapacity);
|
internal static partial int Internal_ReadOutputLogs([MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, FlaxEngine.Interop.NativeString>), CountElementName = "outCapacity")] ref string[] outMessages, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 3)] ref byte[] outLogTypes, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I8, SizeParamIndex = 3)] ref long[] outLogTimes, int outCapacity);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetPlayMode")]
|
||||||
internal static partial void Internal_SetPlayMode([MarshalAs(UnmanagedType.U1)] bool value);
|
internal static partial void Internal_SetPlayMode([MarshalAs(UnmanagedType.U1)] bool value);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
internal static string Internal_GetProjectPath()
|
||||||
internal static partial string Internal_GetProjectPath();
|
{
|
||||||
|
Internal_GetProjectPath(out string projectPath);
|
||||||
|
return projectPath;
|
||||||
|
}
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
|
internal static partial void Internal_GetProjectPath([MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller))] out string projectPath);
|
||||||
|
|
||||||
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_CloneAssetFile(string dstPath, string srcPath, ref Guid dstId);
|
internal static partial bool Internal_CloneAssetFile(string dstPath, string srcPath, ref Guid dstId);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAudioClipMetadata", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAudioClipMetadata")]
|
||||||
internal static partial void Internal_GetAudioClipMetadata(IntPtr obj, out int originalSize, out int importedSize);
|
internal static partial void Internal_GetAudioClipMetadata(IntPtr obj, out int originalSize, out int importedSize);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_SaveJsonAsset(string outputPath, string data, string typename);
|
internal static partial bool Internal_SaveJsonAsset(string outputPath, string data, string typename);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CopyCache", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CopyCache")]
|
||||||
internal static partial void Internal_CopyCache(ref Guid dstId, ref Guid srcId);
|
internal static partial void Internal_CopyCache(ref Guid dstId, ref Guid srcId);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_BakeLightmaps", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_BakeLightmaps")]
|
||||||
internal static partial void Internal_BakeLightmaps([MarshalAs(UnmanagedType.U1)] bool cancel);
|
internal static partial void Internal_BakeLightmaps([MarshalAs(UnmanagedType.U1)] bool cancel);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
|
[return: MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller))]
|
||||||
internal static partial string Internal_GetShaderAssetSourceCode(IntPtr obj);
|
internal static partial string Internal_GetShaderAssetSourceCode(IntPtr obj);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_CookMeshCollision(string path, CollisionDataType type, IntPtr model, int modelLodIndex, uint materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int convexVertexLimit);
|
internal static partial bool Internal_CookMeshCollision(string path, CollisionDataType type, IntPtr model, int modelLodIndex, uint materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int convexVertexLimit);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetCollisionWires", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetCollisionWires")]
|
||||||
internal static partial void Internal_GetCollisionWires(IntPtr collisionData, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "trianglesCount")] out Float3[] triangles, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "indicesCount")] out int[] indices, out int trianglesCount, out int indicesCount);
|
internal static partial void Internal_GetCollisionWires(IntPtr collisionData, [MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<,>), CountElementName = "trianglesCount")] out Float3[] triangles, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "indicesCount")] out int[] indices, out int trianglesCount, out int indicesCount);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetEditorBoxWithChildren", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetEditorBoxWithChildren")]
|
||||||
internal static partial void Internal_GetEditorBoxWithChildren(IntPtr obj, out BoundingBox resultAsRef);
|
internal static partial void Internal_GetEditorBoxWithChildren(IntPtr obj, out BoundingBox resultAsRef);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetOptions")]
|
||||||
internal static partial void Internal_SetOptions(ref InternalOptions options);
|
internal static partial void Internal_SetOptions(ref InternalOptions options);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DrawNavMesh", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DrawNavMesh")]
|
||||||
internal static partial void Internal_DrawNavMesh();
|
internal static partial void Internal_DrawNavMesh();
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloseSplashScreen", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloseSplashScreen")]
|
||||||
internal static partial void Internal_CloseSplashScreen();
|
internal static partial void Internal_CloseSplashScreen();
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_CreateVisualScript(string outputPath, string baseTypename);
|
internal static partial bool Internal_CreateVisualScript(string outputPath, string baseTypename);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
internal static partial string Internal_CanImport(string extension);
|
internal static partial string Internal_CanImport(string extension);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_CanExport(string path);
|
internal static partial bool Internal_CanExport(string path);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_Export(string inputPath, string outputFolder);
|
internal static partial bool Internal_Export(string inputPath, string outputFolder);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsEveryAssemblyLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsEveryAssemblyLoaded")]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_GetIsEveryAssemblyLoaded();
|
internal static partial bool Internal_GetIsEveryAssemblyLoaded();
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetLastProjectOpenedEngineBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetLastProjectOpenedEngineBuild")]
|
||||||
internal static partial int Internal_GetLastProjectOpenedEngineBuild();
|
internal static partial int Internal_GetLastProjectOpenedEngineBuild();
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsCSGActive", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsCSGActive")]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_GetIsCSGActive();
|
internal static partial bool Internal_GetIsCSGActive();
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_RunVisualScriptBreakpointLoopTick", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_RunVisualScriptBreakpointLoopTick")]
|
||||||
internal static partial void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime);
|
internal static partial void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
|
||||||
internal static partial void Internal_DeserializeSceneObject(IntPtr sceneObject, string json);
|
internal static partial void Internal_DeserializeSceneObject(IntPtr sceneObject, string json);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_LoadAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_LoadAsset")]
|
||||||
internal static partial void Internal_LoadAsset(ref Guid id);
|
internal static partial void Internal_LoadAsset(ref Guid id);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanSetToRoot", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanSetToRoot")]
|
||||||
[return: MarshalAs(UnmanagedType.U1)]
|
[return: MarshalAs(UnmanagedType.U1)]
|
||||||
internal static partial bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot);
|
internal static partial bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime")]
|
||||||
internal static partial float Internal_GetAnimationTime(IntPtr animatedModel);
|
internal static partial float Internal_GetAnimationTime(IntPtr animatedModel);
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetAnimationTime")]
|
||||||
internal static partial void Internal_SetAnimationTime(IntPtr animatedModel, float time);
|
internal static partial void Internal_SetAnimationTime(IntPtr animatedModel, float time);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ namespace FlaxEditor.GUI
|
|||||||
private void DoDrag()
|
private void DoDrag()
|
||||||
{
|
{
|
||||||
// Do the drag drop operation if has selected element
|
// Do the drag drop operation if has selected element
|
||||||
if (new Rectangle(Float2.Zero, Size).Contains(ref _mouseDownPos))
|
if (new Rectangle(Float2.Zero, Size).Contains(_mouseDownPos))
|
||||||
{
|
{
|
||||||
if (Validator.SelectedAsset != null)
|
if (Validator.SelectedAsset != null)
|
||||||
DoDragDrop(DragAssets.GetDragData(Validator.SelectedAsset));
|
DoDragDrop(DragAssets.GetDragData(Validator.SelectedAsset));
|
||||||
|
|||||||
@@ -502,7 +502,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
if (base.OnKeyDown(key))
|
if (base.OnKeyDown(key))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Keyboard navigation around the menu
|
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
case KeyboardKeys.ArrowDown:
|
case KeyboardKeys.ArrowDown:
|
||||||
@@ -527,20 +526,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KeyboardKeys.ArrowRight:
|
|
||||||
for (int i = 0; i < _panel.Children.Count; i++)
|
|
||||||
{
|
|
||||||
if (_panel.Children[i] is ContextMenuChildMenu item && item.Visible && item.IsFocused && !item.ContextMenu.IsOpened)
|
|
||||||
{
|
|
||||||
item.ShowChild(this);
|
|
||||||
item.ContextMenu._panel.Children.FirstOrDefault(x => x is ContextMenuButton && x.Visible)?.Focus();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KeyboardKeys.ArrowLeft:
|
|
||||||
ParentCM?.RootWindow.Focus();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -75,11 +75,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HasChildCMOpened => _childCM != null;
|
public bool HasChildCMOpened => _childCM != null;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the parent context menu (if exists).
|
|
||||||
/// </summary>
|
|
||||||
public ContextMenuBase ParentCM => _parentCM;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the topmost context menu.
|
/// Gets the topmost context menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -89,7 +84,9 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
{
|
{
|
||||||
var cm = this;
|
var cm = this;
|
||||||
while (cm._parentCM != null && cm._isSubMenu)
|
while (cm._parentCM != null && cm._isSubMenu)
|
||||||
|
{
|
||||||
cm = cm._parentCM;
|
cm = cm._parentCM;
|
||||||
|
}
|
||||||
return cm;
|
return cm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,11 +111,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool UseInput = true;
|
public bool UseInput = true;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Optional flag that can disable UI navigation (tab/enter).
|
|
||||||
/// </summary>
|
|
||||||
public bool UseNavigation = true;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ContextMenuBase"/> class.
|
/// Initializes a new instance of the <see cref="ContextMenuBase"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -279,7 +271,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
_window.GotFocus += OnWindowGotFocus;
|
_window.GotFocus += OnWindowGotFocus;
|
||||||
_window.LostFocus += OnWindowLostFocus;
|
_window.LostFocus += OnWindowLostFocus;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_IS_FOREGROUND && USE_SDL_WORKAROUNDS
|
#if USE_IS_FOREGROUND && USE_SDL_WORKAROUNDS
|
||||||
// The focus between popup and parent windows doesn't change, force hide the popup when clicked on parent
|
// The focus between popup and parent windows doesn't change, force hide the popup when clicked on parent
|
||||||
parentWin.Window.MouseDown += OnWindowMouseDown;
|
parentWin.Window.MouseDown += OnWindowMouseDown;
|
||||||
@@ -630,21 +622,6 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
case KeyboardKeys.Escape:
|
case KeyboardKeys.Escape:
|
||||||
Hide();
|
Hide();
|
||||||
return true;
|
return true;
|
||||||
case KeyboardKeys.Return:
|
|
||||||
if (UseNavigation && Root?.FocusedControl != null)
|
|
||||||
{
|
|
||||||
Root.SubmitFocused();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KeyboardKeys.Tab:
|
|
||||||
if (UseNavigation && Root != null)
|
|
||||||
{
|
|
||||||
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
|
|
||||||
Root.Navigate(shiftDown ? NavDirection.Previous : NavDirection.Next);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
CloseMenuOnClick = false;
|
CloseMenuOnClick = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ShowChild(ContextMenu parentContextMenu)
|
private void ShowChild(ContextMenu parentContextMenu)
|
||||||
{
|
{
|
||||||
// Hide parent CM popups and set itself as child
|
// Hide parent CM popups and set itself as child
|
||||||
var vAlign = parentContextMenu.ItemsAreaMargin.Top;
|
var vAlign = parentContextMenu.ItemsAreaMargin.Top;
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace FlaxEditor.GUI
|
|||||||
for (int i = 0; i < children.Count; i++)
|
for (int i = 0; i < children.Count; i++)
|
||||||
{
|
{
|
||||||
if (children[i] is KeyframePoint p)
|
if (children[i] is KeyframePoint p)
|
||||||
p.IsSelected = p.Bounds.Intersects(ref selectionRect);
|
p.IsSelected = p.Bounds.Intersects(selectionRect);
|
||||||
}
|
}
|
||||||
_editor.UpdateTangents();
|
_editor.UpdateTangents();
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ namespace FlaxEditor.GUI
|
|||||||
internal void OnMove(Float2 location)
|
internal void OnMove(Float2 location)
|
||||||
{
|
{
|
||||||
// Skip updating keyframes until move actual starts to be meaningful
|
// Skip updating keyframes until move actual starts to be meaningful
|
||||||
if (Float2.Distance(ref _movingSelectionStartPosLock, ref location) < 1.5f)
|
if (Float2.Distance(_movingSelectionStartPosLock, location) < 1.5f)
|
||||||
return;
|
return;
|
||||||
_movingSelectionStartPosLock = Float2.Minimum;
|
_movingSelectionStartPosLock = Float2.Minimum;
|
||||||
|
|
||||||
@@ -522,16 +522,6 @@ namespace FlaxEditor.GUI
|
|||||||
cm.AddButton("Show whole curve", _editor.ShowWholeCurve);
|
cm.AddButton("Show whole curve", _editor.ShowWholeCurve);
|
||||||
cm.AddButton("Reset view", _editor.ResetView);
|
cm.AddButton("Reset view", _editor.ResetView);
|
||||||
}
|
}
|
||||||
cm.AddSeparator();
|
|
||||||
var presetCm = cm.AddChildMenu("Apply preset");
|
|
||||||
foreach (var value in Enum.GetValues(typeof(CurvePreset)))
|
|
||||||
{
|
|
||||||
CurvePreset preset = (CurvePreset)value;
|
|
||||||
string name = Utilities.Utils.GetPropertyNameUI(preset.ToString());
|
|
||||||
var b = presetCm.ContextMenu.AddButton(name, () => _editor.ApplyPreset(preset));
|
|
||||||
b.Enabled = !(_editor is LinearCurveEditor<T> && (preset != CurvePreset.Constant && preset != CurvePreset.Linear));
|
|
||||||
}
|
|
||||||
|
|
||||||
_editor.OnShowContextMenu(cm, selectionCount);
|
_editor.OnShowContextMenu(cm, selectionCount);
|
||||||
cm.Show(this, location);
|
cm.Show(this, location);
|
||||||
}
|
}
|
||||||
@@ -629,33 +619,6 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A list of avaliable curve presets for the <see cref="CurveEditor{T}"/>.
|
|
||||||
/// </summary>
|
|
||||||
public enum CurvePreset
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A curve where every point has the same value.
|
|
||||||
/// </summary>
|
|
||||||
Constant,
|
|
||||||
/// <summary>
|
|
||||||
/// A curve linear curve.
|
|
||||||
/// </summary>
|
|
||||||
Linear,
|
|
||||||
/// <summary>
|
|
||||||
/// A curve that starts a slowly and then accelerates until the end.
|
|
||||||
/// </summary>
|
|
||||||
EaseIn,
|
|
||||||
/// <summary>
|
|
||||||
/// A curve that starts a steep and then flattens until the end.
|
|
||||||
/// </summary>
|
|
||||||
EaseOut,
|
|
||||||
/// <summary>
|
|
||||||
/// A combination of the <see cref="CurvePreset.EaseIn"/> and <see cref="CurvePreset.EaseOut"/> preset.
|
|
||||||
/// </summary>
|
|
||||||
Smoothstep
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnKeyframesDeselect(IKeyframesEditor editor)
|
public override void OnKeyframesDeselect(IKeyframesEditor editor)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,48 +19,6 @@ namespace FlaxEditor.GUI
|
|||||||
/// <seealso cref="CurveEditorBase" />
|
/// <seealso cref="CurveEditorBase" />
|
||||||
public abstract partial class CurveEditor<T> : CurveEditorBase where T : new()
|
public abstract partial class CurveEditor<T> : CurveEditorBase where T : new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Represents a single point in a <see cref="CurveEditorPreset"/>.
|
|
||||||
/// </summary>
|
|
||||||
protected struct CurvePresetPoint
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The time.
|
|
||||||
/// </summary>
|
|
||||||
public float Time;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The value.
|
|
||||||
/// </summary>
|
|
||||||
public float Value;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The in tangent. Will be ignored in <see cref="LinearCurveEditor{T}"/>
|
|
||||||
/// </summary>
|
|
||||||
public float TangentIn;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The out tangent. Will be ignored in <see cref="LinearCurveEditor{T}"/>
|
|
||||||
/// </summary>
|
|
||||||
public float TangentOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A curve preset.
|
|
||||||
/// </summary>
|
|
||||||
protected struct CurveEditorPreset()
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// If the tangents will be linear or smooth.
|
|
||||||
/// </summary>
|
|
||||||
public bool LinearTangents;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The points of the preset.
|
|
||||||
/// </summary>
|
|
||||||
public List<CurvePresetPoint> Points;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Popup : ContextMenuBase
|
private class Popup : ContextMenuBase
|
||||||
{
|
{
|
||||||
private CustomEditorPresenter _presenter;
|
private CustomEditorPresenter _presenter;
|
||||||
@@ -68,12 +26,11 @@ namespace FlaxEditor.GUI
|
|||||||
private List<int> _keyframeIndices;
|
private List<int> _keyframeIndices;
|
||||||
private bool _isDirty;
|
private bool _isDirty;
|
||||||
|
|
||||||
public Popup(CurveEditor<T> editor, object[] selection, List<int> keyframeIndices = null, float maxHeight = 140.0f)
|
public Popup(CurveEditor<T> editor, object[] selection, List<int> keyframeIndices = null, float height = 140.0f)
|
||||||
: this(editor, maxHeight)
|
: this(editor, height)
|
||||||
{
|
{
|
||||||
_presenter.Select(selection);
|
_presenter.Select(selection);
|
||||||
_presenter.OpenAllGroups();
|
_presenter.OpenAllGroups();
|
||||||
Size = new Float2(Size.X, Mathf.Min(_presenter.ContainerControl.Size.Y, maxHeight));
|
|
||||||
_keyframeIndices = keyframeIndices;
|
_keyframeIndices = keyframeIndices;
|
||||||
if (keyframeIndices != null && selection.Length != keyframeIndices.Count)
|
if (keyframeIndices != null && selection.Length != keyframeIndices.Count)
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
@@ -212,7 +169,7 @@ namespace FlaxEditor.GUI
|
|||||||
if (IsSelected)
|
if (IsSelected)
|
||||||
color = Editor.ContainsFocus ? style.SelectionBorder : Color.Lerp(style.ForegroundDisabled, style.SelectionBorder, 0.4f);
|
color = Editor.ContainsFocus ? style.SelectionBorder : Color.Lerp(style.ForegroundDisabled, style.SelectionBorder, 0.4f);
|
||||||
if (IsMouseOver)
|
if (IsMouseOver)
|
||||||
color *= 1.5f;
|
color *= 1.1f;
|
||||||
Render2D.FillRectangle(rect, color);
|
Render2D.FillRectangle(rect, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +285,7 @@ namespace FlaxEditor.GUI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The keyframes size.
|
/// The keyframes size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected static readonly Float2 KeyframesSize = new Float2(8.0f);
|
protected static readonly Float2 KeyframesSize = new Float2(7.0f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The colors for the keyframe points.
|
/// The colors for the keyframe points.
|
||||||
@@ -369,63 +326,6 @@ namespace FlaxEditor.GUI
|
|||||||
private Color _labelsColor;
|
private Color _labelsColor;
|
||||||
private Font _labelsFont;
|
private Font _labelsFont;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Preset values for <see cref="CurvePreset"/> to be applied to a <see cref="CurveEditor{T}"/>.
|
|
||||||
/// </summary>
|
|
||||||
protected Dictionary<CurvePreset, CurveEditorPreset> Presets = new Dictionary<CurvePreset, CurveEditorPreset>
|
|
||||||
{
|
|
||||||
{ CurvePreset.Constant, new CurveEditorPreset
|
|
||||||
{
|
|
||||||
LinearTangents = true,
|
|
||||||
Points = new List<CurvePresetPoint>
|
|
||||||
{
|
|
||||||
new CurvePresetPoint { Time = 0f, Value = 0.5f, TangentIn = 0f, TangentOut = 0f },
|
|
||||||
new CurvePresetPoint { Time = 1f, Value = 0.5f, TangentIn = 0f, TangentOut = 0f },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ CurvePreset.EaseIn, new CurveEditorPreset
|
|
||||||
{
|
|
||||||
LinearTangents = false,
|
|
||||||
Points = new List<CurvePresetPoint>
|
|
||||||
{
|
|
||||||
new CurvePresetPoint { Time = 0f, Value = 0f, TangentIn = 0f, TangentOut = 0f },
|
|
||||||
new CurvePresetPoint { Time = 1f, Value = 1f, TangentIn = -1.4f, TangentOut = 0f },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ CurvePreset.EaseOut, new CurveEditorPreset
|
|
||||||
{
|
|
||||||
LinearTangents = false,
|
|
||||||
Points = new List<CurvePresetPoint>
|
|
||||||
{
|
|
||||||
new CurvePresetPoint { Time = 1f, Value = 1f, TangentIn = 0f, TangentOut = 0f },
|
|
||||||
new CurvePresetPoint { Time = 0f, Value = 0f, TangentIn = 0f, TangentOut = 1.4f },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ CurvePreset.Linear, new CurveEditorPreset
|
|
||||||
{
|
|
||||||
LinearTangents = true,
|
|
||||||
Points = new List<CurvePresetPoint>
|
|
||||||
{
|
|
||||||
new CurvePresetPoint { Time = 0f, Value = 0f, TangentIn = 0f, TangentOut = 0f },
|
|
||||||
new CurvePresetPoint { Time = 1f, Value = 1f, TangentIn = 0f, TangentOut = 0f },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ CurvePreset.Smoothstep, new CurveEditorPreset
|
|
||||||
{
|
|
||||||
LinearTangents = false,
|
|
||||||
Points = new List<CurvePresetPoint>
|
|
||||||
{
|
|
||||||
new CurvePresetPoint { Time = 0f, Value = 0f, TangentIn = 0f, TangentOut = 0f },
|
|
||||||
new CurvePresetPoint { Time = 1f, Value = 1f, TangentIn = 0f, TangentOut = 0f },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The keyframe UI points.
|
/// The keyframe UI points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -668,28 +568,6 @@ namespace FlaxEditor.GUI
|
|||||||
/// <param name="indicesToRemove">The list of indices of the keyframes to remove.</param>
|
/// <param name="indicesToRemove">The list of indices of the keyframes to remove.</param>
|
||||||
protected abstract void RemoveKeyframesInternal(HashSet<int> indicesToRemove);
|
protected abstract void RemoveKeyframesInternal(HashSet<int> indicesToRemove);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to convert a float to the type of the type wildcard of the curve editor.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The float.</param>
|
|
||||||
/// <returns>The converted value.</returns>
|
|
||||||
public static object ConvertCurvePresetValueToCurveEditorType(float value)
|
|
||||||
{
|
|
||||||
if (typeof(T) == typeof(Float2))
|
|
||||||
return new Float2(value);
|
|
||||||
if (typeof(T) == typeof(Float3))
|
|
||||||
return new Float3(value);
|
|
||||||
if (typeof(T) == typeof(Float4))
|
|
||||||
return new Float4(value);
|
|
||||||
if (typeof(T) == typeof(Vector2))
|
|
||||||
return new Vector2(value);
|
|
||||||
if (typeof(T) == typeof(Vector3))
|
|
||||||
return new Vector3(value);
|
|
||||||
if (typeof(T) == typeof(Vector4))
|
|
||||||
return new Vector4(value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when showing a context menu. Can be used to add custom buttons with actions.
|
/// Called when showing a context menu. Can be used to add custom buttons with actions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -811,8 +689,8 @@ namespace FlaxEditor.GUI
|
|||||||
if (selectedOnly && !point.IsSelected)
|
if (selectedOnly && !point.IsSelected)
|
||||||
continue;
|
continue;
|
||||||
var pos = point.Point;
|
var pos = point.Point;
|
||||||
Float2.Min(ref posMin, ref pos, out posMin);
|
Float2.Min(posMin, pos, out posMin);
|
||||||
Float2.Max(ref posMax, ref pos, out posMax);
|
Float2.Max(posMax, pos, out posMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply margin around the area
|
// Apply margin around the area
|
||||||
@@ -825,16 +703,16 @@ namespace FlaxEditor.GUI
|
|||||||
PointFromKeyframesToContents(ref posMin, ref viewRect);
|
PointFromKeyframesToContents(ref posMin, ref viewRect);
|
||||||
PointFromKeyframesToContents(ref posMax, ref viewRect);
|
PointFromKeyframesToContents(ref posMax, ref viewRect);
|
||||||
var tmp = posMin;
|
var tmp = posMin;
|
||||||
Float2.Min(ref posMin, ref posMax, out posMin);
|
Float2.Min(posMin, posMax, out posMin);
|
||||||
Float2.Max(ref posMax, ref tmp, out posMax);
|
Float2.Max(posMax, tmp, out posMax);
|
||||||
var contentsSize = posMax - posMin;
|
var contentsSize = posMax - posMin;
|
||||||
|
|
||||||
// Convert from Contents to Main Panel
|
// Convert from Contents to Main Panel
|
||||||
posMin = _contents.PointToParent(posMin);
|
posMin = _contents.PointToParent(posMin);
|
||||||
posMax = _contents.PointToParent(posMax);
|
posMax = _contents.PointToParent(posMax);
|
||||||
tmp = posMin;
|
tmp = posMin;
|
||||||
Float2.Min(ref posMin, ref posMax, out posMin);
|
Float2.Min(posMin, posMax, out posMin);
|
||||||
Float2.Max(ref posMax, ref tmp, out posMax);
|
Float2.Max(posMax, tmp, out posMax);
|
||||||
|
|
||||||
// Update zoom (leave unchanged when focusing a single point)
|
// Update zoom (leave unchanged when focusing a single point)
|
||||||
var zoomMask = EnableZoom;
|
var zoomMask = EnableZoom;
|
||||||
@@ -874,17 +752,6 @@ namespace FlaxEditor.GUI
|
|||||||
ShowCurve(false);
|
ShowCurve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Applies a <see cref="CurvePreset"/> to the curve editor.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="preset">The preset.</param>
|
|
||||||
public virtual void ApplyPreset(CurvePreset preset)
|
|
||||||
{
|
|
||||||
// Remove existing keyframes
|
|
||||||
SelectAll();
|
|
||||||
RemoveKeyframes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Evaluate(out object result, float time, bool loop = false)
|
public override void Evaluate(out object result, float time, bool loop = false)
|
||||||
{
|
{
|
||||||
@@ -1074,7 +941,7 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
SetupGrid(out var min, out var max, out var pixelRange);
|
SetupGrid(out var min, out var max, out var pixelRange);
|
||||||
|
|
||||||
Render2D.PushClip(ref viewRect);
|
Render2D.PushClip(viewRect);
|
||||||
|
|
||||||
if ((ShowAxes & UseMode.Vertical) == UseMode.Vertical)
|
if ((ShowAxes & UseMode.Vertical) == UseMode.Vertical)
|
||||||
DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X);
|
DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X);
|
||||||
@@ -1087,7 +954,7 @@ namespace FlaxEditor.GUI
|
|||||||
// Draw curve
|
// Draw curve
|
||||||
if (!_showCollapsed)
|
if (!_showCollapsed)
|
||||||
{
|
{
|
||||||
Render2D.PushClip(ref rect);
|
Render2D.PushClip(rect);
|
||||||
DrawCurve(ref viewRect);
|
DrawCurve(ref viewRect);
|
||||||
Render2D.PopClip();
|
Render2D.PopClip();
|
||||||
}
|
}
|
||||||
@@ -1161,31 +1028,6 @@ namespace FlaxEditor.GUI
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool left = key == KeyboardKeys.ArrowLeft;
|
|
||||||
bool right = key == KeyboardKeys.ArrowRight;
|
|
||||||
bool up = key == KeyboardKeys.ArrowUp;
|
|
||||||
bool down = key == KeyboardKeys.ArrowDown;
|
|
||||||
|
|
||||||
if (left || right || up || down)
|
|
||||||
{
|
|
||||||
bool shift = Root.GetKey(KeyboardKeys.Shift);
|
|
||||||
bool alt = Root.GetKey(KeyboardKeys.Alt);
|
|
||||||
float deltaValue = 10f;
|
|
||||||
if (shift || alt)
|
|
||||||
deltaValue = shift ? 2.5f : 5f;
|
|
||||||
|
|
||||||
Float2 moveDelta = Float2.Zero;
|
|
||||||
if (left || right)
|
|
||||||
moveDelta.X = left ? -deltaValue : deltaValue;
|
|
||||||
if (up || down)
|
|
||||||
moveDelta.Y = up ? -deltaValue : deltaValue;
|
|
||||||
|
|
||||||
_contents.OnMoveStart(Float2.Zero);
|
|
||||||
_contents.OnMove(moveDelta);
|
|
||||||
_contents.OnMoveEnd(Float2.Zero);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1684,22 +1526,6 @@ namespace FlaxEditor.GUI
|
|||||||
_tangents[i].Visible = false;
|
_tangents[i].Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void ApplyPreset(CurvePreset preset)
|
|
||||||
{
|
|
||||||
base.ApplyPreset(preset);
|
|
||||||
|
|
||||||
CurveEditorPreset data = Presets[preset];
|
|
||||||
foreach (var point in data.Points)
|
|
||||||
{
|
|
||||||
float time = point.Time;
|
|
||||||
object value = ConvertCurvePresetValueToCurveEditorType((float)point.Value);
|
|
||||||
AddKeyframe(time, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowWholeCurve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void DrawCurve(ref Rectangle viewRect)
|
protected override void DrawCurve(ref Rectangle viewRect)
|
||||||
{
|
{
|
||||||
@@ -2486,30 +2312,6 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void ApplyPreset(CurvePreset preset)
|
|
||||||
{
|
|
||||||
base.ApplyPreset(preset);
|
|
||||||
|
|
||||||
CurveEditorPreset data = Presets[preset];
|
|
||||||
|
|
||||||
foreach (var point in data.Points)
|
|
||||||
{
|
|
||||||
float time = point.Time;
|
|
||||||
object value = ConvertCurvePresetValueToCurveEditorType((float)point.Value);
|
|
||||||
object tangentIn = ConvertCurvePresetValueToCurveEditorType((float)point.TangentIn);
|
|
||||||
object tangentOut = ConvertCurvePresetValueToCurveEditorType((float)point.TangentOut);
|
|
||||||
|
|
||||||
AddKeyframe(time, value, tangentIn, tangentOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
SelectAll();
|
|
||||||
if (data.LinearTangents)
|
|
||||||
SetTangentsLinear();
|
|
||||||
|
|
||||||
ShowWholeCurve();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void SetScaleInternal(ref Float2 scale)
|
protected override void SetScaleInternal(ref Float2 scale)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
private bool _useDynamicEditing;
|
private bool _useDynamicEditing;
|
||||||
private bool _activeEyedropper;
|
private bool _activeEyedropper;
|
||||||
private bool _canPassLastChangeEvent = true;
|
private bool _canPassLastChangeEvent = true;
|
||||||
private bool _linear;
|
|
||||||
private ColorValueBox.ColorPickerEvent _onChanged;
|
private ColorValueBox.ColorPickerEvent _onChanged;
|
||||||
private ColorValueBox.ColorPickerClosedEvent _onClosed;
|
private ColorValueBox.ColorPickerClosedEvent _onClosed;
|
||||||
|
|
||||||
@@ -57,7 +56,6 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
private Button _cCancel;
|
private Button _cCancel;
|
||||||
private Button _cOK;
|
private Button _cOK;
|
||||||
private Button _cEyedropper;
|
private Button _cEyedropper;
|
||||||
private Button _cLinearSRGB;
|
|
||||||
|
|
||||||
private List<Color> _savedColors = new List<Color>();
|
private List<Color> _savedColors = new List<Color>();
|
||||||
private List<Button> _savedColorButtons = new List<Button>();
|
private List<Button> _savedColorButtons = new List<Button>();
|
||||||
@@ -120,7 +118,6 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
_value = Color.Transparent;
|
_value = Color.Transparent;
|
||||||
_onChanged = colorChanged;
|
_onChanged = colorChanged;
|
||||||
_onClosed = pickerClosed;
|
_onClosed = pickerClosed;
|
||||||
_linear = !Graphics.GammaColorSpace;
|
|
||||||
|
|
||||||
// Get saved colors if they exist
|
// Get saved colors if they exist
|
||||||
if (Editor.Instance.ProjectCache.TryGetCustomData("ColorPickerSavedColors", out string savedColors))
|
if (Editor.Instance.ProjectCache.TryGetCustomData("ColorPickerSavedColors", out string savedColors))
|
||||||
@@ -230,25 +227,6 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
_cEyedropper.Width = _cEyedropper.Height;
|
_cEyedropper.Width = _cEyedropper.Height;
|
||||||
_cEyedropper.X -= _cEyedropper.Width;
|
_cEyedropper.X -= _cEyedropper.Width;
|
||||||
|
|
||||||
// Linear/sRGB toggle button
|
|
||||||
_cLinearSRGB = new Button(_cOK.X - EyedropperMargin, _cHex.Bottom + PickerMargin)
|
|
||||||
{
|
|
||||||
TooltipText = "Toggles between color preview in Linear and sRGB",
|
|
||||||
BackgroundBrush = new SpriteBrush(Editor.Instance.Icons.SplineAligned64),
|
|
||||||
BackgroundColor = _cEyedropper.BackgroundColor,
|
|
||||||
BackgroundColorHighlighted = _cEyedropper.BackgroundColorHighlighted,
|
|
||||||
BorderColor = _linear ? Color.Transparent : style.Foreground,
|
|
||||||
BorderColorHighlighted = _cEyedropper.BorderColorHighlighted,
|
|
||||||
Size = _cEyedropper.Size,
|
|
||||||
Parent = this,
|
|
||||||
Location = _cEyedropper.BottomLeft + new Float2(0, 4),
|
|
||||||
};
|
|
||||||
_cLinearSRGB.Clicked += () =>
|
|
||||||
{
|
|
||||||
_linear = !_linear;
|
|
||||||
_cLinearSRGB.BorderColor = _linear ? Color.Transparent : style.Foreground;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set initial color
|
// Set initial color
|
||||||
SelectedColor = initialValue;
|
SelectedColor = initialValue;
|
||||||
}
|
}
|
||||||
@@ -303,22 +281,16 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
if (_activeEyedropper)
|
if (_activeEyedropper)
|
||||||
{
|
{
|
||||||
_activeEyedropper = false;
|
_activeEyedropper = false;
|
||||||
if (colorPicked != Color.Transparent)
|
SelectedColor = colorPicked;
|
||||||
{
|
ScreenUtilities.PickColorDone -= OnColorPicked;
|
||||||
Color color = colorPicked;
|
|
||||||
if (_linear)
|
|
||||||
color = color.ToLinear();
|
|
||||||
SelectedColor = color;
|
|
||||||
}
|
|
||||||
Platform.PickScreenColorDone -= OnColorPicked;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEyedropStart()
|
private void OnEyedropStart()
|
||||||
{
|
{
|
||||||
_activeEyedropper = true;
|
_activeEyedropper = true;
|
||||||
Platform.PickScreenColor();
|
ScreenUtilities.PickColor();
|
||||||
Platform.PickScreenColorDone += OnColorPicked;
|
ScreenUtilities.PickColorDone += OnColorPicked;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRGBAChanged()
|
private void OnRGBAChanged()
|
||||||
@@ -356,13 +328,9 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
{
|
{
|
||||||
// Try reading the color under the cursor in realtime if supported by the platform
|
// Try reading the color under the cursor in realtime if supported by the platform
|
||||||
Float2 mousePosition = Platform.MousePosition;
|
Float2 mousePosition = Platform.MousePosition;
|
||||||
Color color = Platform.GetScreenColorAt(mousePosition);
|
Color color = ScreenUtilities.GetColorAt(mousePosition);
|
||||||
if (color != Color.Transparent)
|
if (color != Color.Transparent)
|
||||||
{
|
|
||||||
if (_linear)
|
|
||||||
color = color.ToLinear();
|
|
||||||
SelectedColor = color;
|
SelectedColor = color;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,7 +391,7 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Render2D.FillRectangle(newRect, _linear ? _value.ToSRgb() : _value);
|
Render2D.FillRectangle(newRect, _value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -444,7 +412,7 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
{
|
{
|
||||||
// Cancel eye dropping
|
// Cancel eye dropping
|
||||||
_activeEyedropper = false;
|
_activeEyedropper = false;
|
||||||
Platform.PickScreenColorDone -= OnColorPicked;
|
ScreenUtilities.PickColorDone -= OnColorPicked;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -310,26 +310,6 @@ namespace FlaxEditor.GUI.Dialogs
|
|||||||
Render2D.DrawRectangle(_slider1Rect, _isMouseDownSlider1 ? style.BackgroundSelected : Color.Black);
|
Render2D.DrawRectangle(_slider1Rect, _isMouseDownSlider1 ? style.BackgroundSelected : Color.Black);
|
||||||
Render2D.DrawRectangle(valueR, _isMouseDownSlider1 ? Color.White : Color.Gray);
|
Render2D.DrawRectangle(valueR, _isMouseDownSlider1 ? Color.White : Color.Gray);
|
||||||
|
|
||||||
// Draw checkerboard pattern to part of the alpha slider background
|
|
||||||
var alphaRect = _slider2Rect;
|
|
||||||
Render2D.FillRectangle(alphaRect, Color.White);
|
|
||||||
var smallRectSize = alphaRect.Width * 0.5f;
|
|
||||||
var numHor = Mathf.CeilToInt(alphaRect.Width / smallRectSize);
|
|
||||||
var numVer = Mathf.CeilToInt(alphaRect.Height / smallRectSize);
|
|
||||||
for (int i = 0; i < numHor; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < numVer; j++)
|
|
||||||
{
|
|
||||||
if ((i + j) % 2 == 0)
|
|
||||||
{
|
|
||||||
var rect = new Rectangle(alphaRect.X + smallRectSize * i, alphaRect.Y + smallRectSize * j, new Float2(smallRectSize));
|
|
||||||
Render2D.PushClip(alphaRect);
|
|
||||||
Render2D.FillRectangle(rect, Color.Gray);
|
|
||||||
Render2D.PopClip();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alpha
|
// Alpha
|
||||||
float alphaY = _slider2Rect.Height * (1 - _color.A);
|
float alphaY = _slider2Rect.Height * (1 - _color.A);
|
||||||
var alphaR = new Rectangle(_slider2Rect.X - slidersOffset, _slider2Rect.Y + alphaY - slidersThickness / 2, _slider2Rect.Width + slidersOffset * 2, slidersThickness);
|
var alphaR = new Rectangle(_slider2Rect.X - slidersOffset, _slider2Rect.Y + alphaY - slidersThickness / 2, _slider2Rect.Width + slidersOffset * 2, slidersThickness);
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
var childPanels = _childPanels.ToArray();
|
var childPanels = _childPanels.ToArray();
|
||||||
if (childPanels.Length != 0)
|
if (childPanels.Length != 0)
|
||||||
{
|
{
|
||||||
// Fallback: move tabs from child panels into this one.
|
// Move tabs from child panels into this one
|
||||||
DockWindow selectedTab = null;
|
DockWindow selectedTab = null;
|
||||||
foreach (var childPanel in childPanels)
|
foreach (var childPanel in childPanels)
|
||||||
{
|
{
|
||||||
@@ -490,8 +490,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
// Unlink splitter
|
// Unlink splitter
|
||||||
var splitterParent = splitter.Parent;
|
var splitterParent = splitter.Parent;
|
||||||
if (splitterParent == null)
|
Assert.IsNotNull(splitterParent);
|
||||||
return;
|
|
||||||
splitter.Parent = null;
|
splitter.Parent = null;
|
||||||
|
|
||||||
// Move controls from second split panel to the split panel parent
|
// Move controls from second split panel to the split panel parent
|
||||||
@@ -508,63 +507,17 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
splitter.Dispose();
|
splitter.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IsMaster && _childPanels.Count != 0)
|
|
||||||
{
|
|
||||||
if (TryCollapseSplitter(_tabsProxy?.Parent as Panel))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (!IsMaster)
|
else if (!IsMaster)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_childPanels.Count != 0)
|
|
||||||
{
|
|
||||||
if (TryCollapseSplitter(_tabsProxy?.Parent as Panel))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (!IsMaster)
|
else if (!IsMaster)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool CollapseEmptyTabsProxy()
|
|
||||||
{
|
|
||||||
if (TabsCount == 0 && ChildPanelsCount > 0)
|
|
||||||
{
|
|
||||||
return TryCollapseSplitter(_tabsProxy?.Parent as Panel);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool TryCollapseSplitter(Panel removedPanelParent)
|
|
||||||
{
|
|
||||||
if (removedPanelParent == null)
|
|
||||||
return false;
|
|
||||||
if (!(removedPanelParent.Parent is SplitPanel tabsSplitter))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var splitterParent = tabsSplitter.Parent;
|
|
||||||
if (splitterParent == null)
|
|
||||||
return false;
|
|
||||||
tabsSplitter.Parent = null;
|
|
||||||
|
|
||||||
var scrPanel = removedPanelParent == tabsSplitter.Panel2 ? tabsSplitter.Panel1 : tabsSplitter.Panel2;
|
|
||||||
var srcPanelChildrenCount = scrPanel.ChildrenCount;
|
|
||||||
for (int i = srcPanelChildrenCount - 1; i >= 0 && scrPanel.ChildrenCount > 0; i--)
|
|
||||||
{
|
|
||||||
scrPanel.GetChild(i).Parent = splitterParent;
|
|
||||||
}
|
|
||||||
Assert.IsTrue(scrPanel.ChildrenCount == 0);
|
|
||||||
Assert.IsTrue(splitterParent.ChildrenCount == srcPanelChildrenCount);
|
|
||||||
|
|
||||||
tabsSplitter.Dispose();
|
|
||||||
if (_tabsProxy != null && _tabsProxy.Parent == removedPanelParent)
|
|
||||||
_tabsProxy = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal virtual void DockWindowInternal(DockState state, DockWindow window, bool autoSelect = true, float? splitterValue = null)
|
internal virtual void DockWindowInternal(DockState state, DockWindow window, bool autoSelect = true, float? splitterValue = null)
|
||||||
{
|
{
|
||||||
DockWindow(state, window, autoSelect, splitterValue);
|
DockWindow(state, window, autoSelect, splitterValue);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// The mouse position.
|
/// The mouse position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Float2 MousePosition = Float2.Minimum;
|
public Float2 MousePosition = Float2.Minimum;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The mouse position.
|
/// The mouse position.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -193,7 +193,6 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
CreateFloating(Float2.Zero, Float2.Zero);
|
CreateFloating(Float2.Zero, Float2.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates the window in a floating state.
|
/// Creates the window in a floating state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
private class FloatWindowDecorations : WindowDecorations
|
private class FloatWindowDecorations : WindowDecorations
|
||||||
{
|
{
|
||||||
private FloatWindowDockPanel _panel;
|
private FloatWindowDockPanel _panel;
|
||||||
|
|
||||||
public FloatWindowDecorations(FloatWindowDockPanel panel)
|
public FloatWindowDecorations(FloatWindowDockPanel panel)
|
||||||
: base(panel.RootWindow)
|
: base(panel.RootWindow)
|
||||||
{
|
{
|
||||||
_panel = panel;
|
_panel = panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
public override bool OnMouseDown(Float2 location, MouseButton button)
|
||||||
{
|
{
|
||||||
@@ -76,19 +76,19 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
Parent = window;
|
Parent = window;
|
||||||
_window.Window.Closing += OnClosing;
|
_window.Window.Closing += OnClosing;
|
||||||
_window.Window.LeftButtonHit += OnLeftButtonHit;
|
_window.Window.LeftButtonHit += OnLeftButtonHit;
|
||||||
|
|
||||||
if (Utilities.Utils.UseCustomWindowDecorations())
|
if (Utilities.Utils.UseCustomWindowDecorations())
|
||||||
{
|
{
|
||||||
var decorations = Parent.AddChild(new FloatWindowDecorations(this));
|
var decorations = Parent.AddChild(new FloatWindowDecorations(this));
|
||||||
decorations.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, false);
|
decorations.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void PerformLayoutBeforeChildren()
|
protected override void PerformLayoutBeforeChildren()
|
||||||
{
|
{
|
||||||
base.PerformLayoutBeforeChildren();
|
base.PerformLayoutBeforeChildren();
|
||||||
|
|
||||||
var decorations = Parent.GetChild<FloatWindowDecorations>();
|
var decorations = Parent.GetChild<FloatWindowDecorations>();
|
||||||
if (decorations != null)
|
if (decorations != null)
|
||||||
{
|
{
|
||||||
@@ -108,11 +108,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Create docking hint window
|
// Create docking hint window
|
||||||
Window dragSourceWindow = null;
|
WindowDragHelper.StartDragging(this);
|
||||||
#if !PLATFORM_SDL
|
|
||||||
dragSourceWindow = _window?.Window;
|
|
||||||
#endif
|
|
||||||
WindowDragHelper.StartDragging(this, dragSourceWindow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -131,15 +127,11 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.Title = title;
|
settings.Title = title;
|
||||||
settings.Size = size;
|
settings.Size = size;
|
||||||
settings.Position = location;
|
settings.Position = location;
|
||||||
settings.MinimumSize = new Float2(100, 100);
|
settings.MinimumSize = new Float2(200, 150);
|
||||||
settings.MaximumSize = Float2.Zero; // Unlimited size
|
settings.MaximumSize = Float2.Zero; // Unlimited size
|
||||||
settings.Fullscreen = false;
|
settings.Fullscreen = false;
|
||||||
settings.HasBorder = true;
|
settings.HasBorder = true;
|
||||||
#if PLATFORM_SDL
|
|
||||||
settings.SupportsTransparency = true;
|
settings.SupportsTransparency = true;
|
||||||
#else
|
|
||||||
settings.SupportsTransparency = false;
|
|
||||||
#endif
|
|
||||||
settings.ActivateWhenFirstShown = true;
|
settings.ActivateWhenFirstShown = true;
|
||||||
settings.AllowInput = true;
|
settings.AllowInput = true;
|
||||||
settings.AllowMinimize = true;
|
settings.AllowMinimize = true;
|
||||||
@@ -151,7 +143,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
settings.ShowAfterFirstPaint = false;
|
settings.ShowAfterFirstPaint = false;
|
||||||
settings.ShowInTaskbar = true;
|
settings.ShowInTaskbar = true;
|
||||||
settings.StartPosition = startPosition;
|
settings.StartPosition = startPosition;
|
||||||
|
|
||||||
if (Utilities.Utils.UseCustomWindowDecorations())
|
if (Utilities.Utils.UseCustomWindowDecorations())
|
||||||
{
|
{
|
||||||
settings.HasBorder = false;
|
settings.HasBorder = false;
|
||||||
@@ -221,12 +213,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
base.OnSelectedTabChanged();
|
base.OnSelectedTabChanged();
|
||||||
|
|
||||||
if (_window != null && SelectedTab != null)
|
if (_window != null && SelectedTab != null)
|
||||||
{
|
|
||||||
_window.Title = SelectedTab.Title;
|
_window.Title = SelectedTab.Title;
|
||||||
var decorations = Parent.GetChild<FloatWindowDecorations>();
|
|
||||||
if (decorations != null)
|
|
||||||
decorations.PerformLayout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The hint control size.
|
/// The hint control size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const float HintControlSize = 48.0f;
|
public const float HintControlSize = 32.0f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The opacity of the dragged window when hint controls are shown.
|
/// The opacity of the dragged window when hint controls are shown.
|
||||||
@@ -44,33 +44,13 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
_toMove = toMove;
|
_toMove = toMove;
|
||||||
_toSet = DockState.Float;
|
_toSet = DockState.Float;
|
||||||
var window = toMove.Window.Window;
|
var window = toMove.Window.Window;
|
||||||
var mousePos = Platform.MousePosition;
|
|
||||||
|
|
||||||
// Check if window is maximized and restore window for correct dragging
|
|
||||||
if (window.IsMaximized)
|
|
||||||
{
|
|
||||||
var windowMousePos = mousePos - window.Position;
|
|
||||||
var previousSize = window.Size;
|
|
||||||
window.Restore();
|
|
||||||
window.Position = mousePos - windowMousePos * window.Size / previousSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When drag starts from a tabs the window might not be shown yet
|
|
||||||
if (!window.IsVisible)
|
|
||||||
{
|
|
||||||
window.Show();
|
|
||||||
window.Position = mousePos - new Float2(40, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind events
|
// Bind events
|
||||||
FlaxEngine.Scripting.Update += OnUpdate;
|
FlaxEngine.Scripting.Update += OnUpdate;
|
||||||
window.MouseUp += OnMouseUp;
|
window.MouseUp += OnMouseUp;
|
||||||
#if !PLATFORM_SDL
|
|
||||||
window.StartTrackingMouse(false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Update rectangles
|
// Update rectangles
|
||||||
UpdateRects(mousePos);
|
UpdateRects(Platform.MousePosition);
|
||||||
|
|
||||||
// Ensure the dragged window stays on top of every other window
|
// Ensure the dragged window stays on top of every other window
|
||||||
window.IsAlwaysOnTop = true;
|
window.IsAlwaysOnTop = true;
|
||||||
@@ -78,21 +58,13 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
_dragSourceWindow = dragSourceWindow;
|
_dragSourceWindow = dragSourceWindow;
|
||||||
if (_dragSourceWindow != null) // Detaching a tab from existing window
|
if (_dragSourceWindow != null) // Detaching a tab from existing window
|
||||||
{
|
{
|
||||||
#if PLATFORM_SDL
|
|
||||||
_dragOffset = new Float2(window.Size.X / 2, 10.0f);
|
_dragOffset = new Float2(window.Size.X / 2, 10.0f);
|
||||||
#else
|
|
||||||
_dragOffset = mousePos - window.Position;
|
_dragSourceWindow.MouseUp += OnMouseUp; // The mouse up event is sent to the source window on Windows
|
||||||
#endif
|
|
||||||
|
|
||||||
// The mouse up event is sent to the source window on Windows
|
|
||||||
_dragSourceWindow.MouseUp += OnMouseUp;
|
|
||||||
|
|
||||||
// TODO: when detaching tab in floating window (not main window), the drag source window is still main window?
|
// TODO: when detaching tab in floating window (not main window), the drag source window is still main window?
|
||||||
var dragSourceWindowWayland = toMove.MasterPanel?.RootWindow.Window ?? Editor.Instance.Windows.MainWindow;
|
var dragSourceWindowWayland = toMove.MasterPanel?.RootWindow.Window ?? Editor.Instance.Windows.MainWindow;
|
||||||
window.DoDragDrop(window.Title, _dragOffset, dragSourceWindowWayland);
|
window.DoDragDrop(window.Title, _dragOffset, dragSourceWindowWayland);
|
||||||
#if !PLATFORM_SDL
|
|
||||||
_dragSourceWindow.BringToFront();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -112,12 +84,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
// Unbind events
|
// Unbind events
|
||||||
FlaxEngine.Scripting.Update -= OnUpdate;
|
FlaxEngine.Scripting.Update -= OnUpdate;
|
||||||
if (window != null)
|
if (window != null)
|
||||||
{
|
|
||||||
window.MouseUp -= OnMouseUp;
|
window.MouseUp -= OnMouseUp;
|
||||||
#if !PLATFORM_SDL
|
|
||||||
window.EndTrackingMouse();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (_dragSourceWindow != null)
|
if (_dragSourceWindow != null)
|
||||||
_dragSourceWindow.MouseUp -= OnMouseUp;
|
_dragSourceWindow.MouseUp -= OnMouseUp;
|
||||||
|
|
||||||
@@ -193,14 +160,13 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
/// Start dragging a floating dock panel.
|
/// Start dragging a floating dock panel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="toMove">Floating dock panel to move.</param>
|
/// <param name="toMove">Floating dock panel to move.</param>
|
||||||
/// <param name="dragSourceWindow">The window where dragging started from.</param>
|
|
||||||
/// <returns>The window drag helper object.</returns>
|
/// <returns>The window drag helper object.</returns>
|
||||||
public static WindowDragHelper StartDragging(FloatWindowDockPanel toMove, Window dragSourceWindow = null)
|
public static WindowDragHelper StartDragging(FloatWindowDockPanel toMove)
|
||||||
{
|
{
|
||||||
if (toMove == null)
|
if (toMove == null)
|
||||||
throw new ArgumentNullException();
|
throw new ArgumentNullException();
|
||||||
|
|
||||||
return new WindowDragHelper(toMove, dragSourceWindow);
|
return new WindowDragHelper(toMove, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -302,8 +268,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prefer panel in the same window we hit earlier
|
// Prefer panel in the same window we hit earlier
|
||||||
// TODO: this doesn't allow docking window into another floating window over the main window
|
if (dockPanel?.RootWindow != _toDock?.RootWindow)
|
||||||
/*if (dockPanel?.RootWindow != _toDock?.RootWindow)
|
|
||||||
{
|
{
|
||||||
foreach (var hit in hitResults)
|
foreach (var hit in hitResults)
|
||||||
{
|
{
|
||||||
@@ -313,7 +278,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dockPanel != _toDock)
|
if (dockPanel != _toDock)
|
||||||
@@ -323,29 +288,19 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
AddDockHints();
|
AddDockHints();
|
||||||
|
|
||||||
// Make sure the all the dock hint areas are not under other windows
|
// Make sure the all the dock hint areas are not under other windows
|
||||||
if (_toDock != Editor.Instance.UI.MasterPanel)
|
_toDock?.RootWindow.Window.BringToFront();
|
||||||
_toDock?.RootWindow.Window.BringToFront();
|
|
||||||
//_toDock?.RootWindow.Window.Focus();
|
//_toDock?.RootWindow.Window.Focus();
|
||||||
|
|
||||||
#if PLATFORM_SDL
|
|
||||||
// Make the dragged window transparent when dock hints are visible
|
// Make the dragged window transparent when dock hints are visible
|
||||||
_toMove.Window.Window.Opacity = _toDock == null ? 1.0f : DragWindowOpacity;
|
_toMove.Window.Window.Opacity = _toDock == null ? 1.0f : DragWindowOpacity;
|
||||||
#else
|
|
||||||
// Bring the drop source always to the top
|
|
||||||
if (_dragSourceWindow != null)
|
|
||||||
_dragSourceWindow.BringToFront();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check dock state to use
|
// Check dock state to use
|
||||||
bool showProxyHints = _toDock != null;
|
bool showProxyHints = _toDock != null;
|
||||||
bool showBorderHints = showProxyHints;
|
bool showBorderHints = showProxyHints;
|
||||||
bool showCenterHint = showProxyHints;
|
bool showCenterHint = showProxyHints;
|
||||||
Control hoveredHintControl = null;
|
Control hoveredHintControl = null;
|
||||||
Float2 hoveredLocationOffset = Float2.Zero;
|
|
||||||
Float2 hoveredSizeOverride = Float2.Zero;
|
Float2 hoveredSizeOverride = Float2.Zero;
|
||||||
DockState prevToSet = _toSet;
|
|
||||||
float hoveredMargin = 1.0f;
|
|
||||||
if (showProxyHints)
|
if (showProxyHints)
|
||||||
{
|
{
|
||||||
// If moved window has not only tabs but also child panels disable docking as tab
|
// If moved window has not only tabs but also child panels disable docking as tab
|
||||||
@@ -362,7 +317,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
// Cache dock rectangles
|
// Cache dock rectangles
|
||||||
var size = _rectDock.Size / Platform.DpiScale;
|
var size = _rectDock.Size / Platform.DpiScale;
|
||||||
var offset = _toDock.PointFromScreen(_rectDock.Location);
|
var offset = _toDock.PointFromScreen(_rectDock.Location);
|
||||||
var borderMargin = 10.0f;
|
var borderMargin = 4.0f;
|
||||||
var hintWindowsSize = HintControlSize;
|
var hintWindowsSize = HintControlSize;
|
||||||
var hintWindowsSize2 = hintWindowsSize * 0.5f;
|
var hintWindowsSize2 = hintWindowsSize * 0.5f;
|
||||||
var hintPreviewSize = new Float2(Math.Max(HintControlSize * 2, size.X * 0.5f), Math.Max(HintControlSize * 2, size.Y * 0.5f));
|
var hintPreviewSize = new Float2(Math.Max(HintControlSize * 2, size.X * 0.5f), Math.Max(HintControlSize * 2, size.Y * 0.5f));
|
||||||
@@ -375,40 +330,35 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
_rCenter = new Rectangle(centerX - hintWindowsSize2, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
|
_rCenter = new Rectangle(centerX - hintWindowsSize2, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
|
||||||
|
|
||||||
// Hit test, and calculate the approximation for filled area when hovered over the hint
|
// Hit test, and calculate the approximation for filled area when hovered over the hint
|
||||||
var toSet = DockState.Float;
|
DockState toSet = DockState.Float;
|
||||||
var hintTestPoint = _toDock.PointFromScreen(_mouse);
|
|
||||||
if (showBorderHints)
|
if (showBorderHints)
|
||||||
{
|
{
|
||||||
if (_rUpper.Contains(ref hintTestPoint))
|
if (_rUpper.Contains(_toDock.PointFromScreen(_mouse)))
|
||||||
{
|
{
|
||||||
toSet = DockState.DockTop;
|
toSet = DockState.DockTop;
|
||||||
hoveredHintControl = _dockHintUp;
|
hoveredHintControl = _dockHintUp;
|
||||||
hoveredSizeOverride = new Float2(size.X, size.Y * DockPanel.DefaultSplitterValue);
|
hoveredSizeOverride = new Float2(size.X, hintPreviewSize.Y);
|
||||||
hoveredLocationOffset.Y -= borderMargin - hoveredMargin;
|
|
||||||
}
|
}
|
||||||
else if (_rBottom.Contains(ref hintTestPoint))
|
else if (_rBottom.Contains(_toDock.PointFromScreen(_mouse)))
|
||||||
{
|
{
|
||||||
toSet = DockState.DockBottom;
|
toSet = DockState.DockBottom;
|
||||||
hoveredHintControl = _dockHintDown;
|
hoveredHintControl = _dockHintDown;
|
||||||
hoveredSizeOverride = new Float2(size.X, size.Y * DockPanel.DefaultSplitterValue);
|
hoveredSizeOverride = new Float2(size.X, hintPreviewSize.Y);
|
||||||
hoveredLocationOffset.Y += borderMargin - hoveredMargin;
|
|
||||||
}
|
}
|
||||||
else if (_rLeft.Contains(ref hintTestPoint))
|
else if (_rLeft.Contains(_toDock.PointFromScreen(_mouse)))
|
||||||
{
|
{
|
||||||
toSet = DockState.DockLeft;
|
toSet = DockState.DockLeft;
|
||||||
hoveredHintControl = _dockHintLeft;
|
hoveredHintControl = _dockHintLeft;
|
||||||
hoveredSizeOverride = new Float2(size.X * DockPanel.DefaultSplitterValue, size.Y);
|
hoveredSizeOverride = new Float2(hintPreviewSize.X, size.Y);
|
||||||
hoveredLocationOffset.X -= borderMargin - hoveredMargin;
|
|
||||||
}
|
}
|
||||||
else if (_rRight.Contains(ref hintTestPoint))
|
else if (_rRight.Contains(_toDock.PointFromScreen(_mouse)))
|
||||||
{
|
{
|
||||||
toSet = DockState.DockRight;
|
toSet = DockState.DockRight;
|
||||||
hoveredHintControl = _dockHintRight;
|
hoveredHintControl = _dockHintRight;
|
||||||
hoveredSizeOverride = new Float2(size.X * DockPanel.DefaultSplitterValue, size.Y);
|
hoveredSizeOverride = new Float2(hintPreviewSize.X, size.Y);
|
||||||
hoveredLocationOffset.X += borderMargin - hoveredMargin;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (showCenterHint && _rCenter.Contains(ref hintTestPoint))
|
if (showCenterHint && _rCenter.Contains(_toDock.PointFromScreen(_mouse)))
|
||||||
{
|
{
|
||||||
toSet = DockState.DockFill;
|
toSet = DockState.DockFill;
|
||||||
hoveredHintControl = _dockHintCenter;
|
hoveredHintControl = _dockHintCenter;
|
||||||
@@ -425,41 +375,38 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
// Update sizes and opacity of hint controls
|
// Update sizes and opacity of hint controls
|
||||||
if (_toDock != null)
|
if (_toDock != null)
|
||||||
{
|
{
|
||||||
var mainColor = Style.Current.Selection;
|
|
||||||
if (hoveredHintControl != _dockHintDown)
|
if (hoveredHintControl != _dockHintDown)
|
||||||
{
|
{
|
||||||
_dockHintDown.Size = new Float2(HintControlSize);
|
_dockHintDown.Size = new Float2(HintControlSize);
|
||||||
_dockHintDown.BackgroundColor = mainColor.AlphaMultiplied(0.6f);
|
_dockHintDown.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
|
||||||
}
|
}
|
||||||
if (hoveredHintControl != _dockHintLeft)
|
if (hoveredHintControl != _dockHintLeft)
|
||||||
{
|
{
|
||||||
_dockHintLeft.Size = new Float2(HintControlSize);
|
_dockHintLeft.Size = new Float2(HintControlSize);
|
||||||
_dockHintLeft.BackgroundColor = mainColor.AlphaMultiplied(0.6f);
|
_dockHintLeft.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
|
||||||
}
|
}
|
||||||
if (hoveredHintControl != _dockHintRight)
|
if (hoveredHintControl != _dockHintRight)
|
||||||
{
|
{
|
||||||
_dockHintRight.Size = new Float2(HintControlSize);
|
_dockHintRight.Size = new Float2(HintControlSize);
|
||||||
_dockHintRight.BackgroundColor = mainColor.AlphaMultiplied(0.6f);
|
_dockHintRight.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
|
||||||
}
|
}
|
||||||
if (hoveredHintControl != _dockHintUp)
|
if (hoveredHintControl != _dockHintUp)
|
||||||
{
|
{
|
||||||
_dockHintUp.Size = new Float2(HintControlSize);
|
_dockHintUp.Size = new Float2(HintControlSize);
|
||||||
_dockHintUp.BackgroundColor = mainColor.AlphaMultiplied(0.6f);
|
_dockHintUp.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
|
||||||
}
|
}
|
||||||
if (hoveredHintControl != _dockHintCenter)
|
if (hoveredHintControl != _dockHintCenter)
|
||||||
{
|
{
|
||||||
_dockHintCenter.Size = new Float2(HintControlSize);
|
_dockHintCenter.Size = new Float2(HintControlSize);
|
||||||
_dockHintCenter.BackgroundColor = mainColor.AlphaMultiplied(0.6f);
|
_dockHintCenter.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_toSet != DockState.Float)
|
if (_toSet != DockState.Float)
|
||||||
{
|
{
|
||||||
if (hoveredHintControl != null)
|
if (hoveredHintControl != null)
|
||||||
{
|
{
|
||||||
hoveredHintControl.BackgroundColor = mainColor;
|
hoveredHintControl.BackgroundColor = Style.Current.Selection.AlphaMultiplied(1.0f);
|
||||||
if (_toSet != prevToSet)
|
hoveredHintControl.Size = hoveredSizeOverride;
|
||||||
hoveredHintControl.Location += hoveredLocationOffset;
|
|
||||||
hoveredHintControl.Size = hoveredSizeOverride - hoveredMargin;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -494,21 +441,18 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
|
|
||||||
private void OnUpdate()
|
private void OnUpdate()
|
||||||
{
|
{
|
||||||
// If the engine lost focus during dragging, end the action
|
|
||||||
if (!Engine.HasFocus)
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var mousePos = Platform.MousePosition;
|
var mousePos = Platform.MousePosition;
|
||||||
if (_mouse != mousePos)
|
|
||||||
{
|
|
||||||
if (_dragSourceWindow != null)
|
|
||||||
_toMove.Window.Window.Position = mousePos - _dragOffset;
|
|
||||||
|
|
||||||
UpdateRects(mousePos);
|
if (_mouse != mousePos)
|
||||||
}
|
OnMouseMove(mousePos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMouseMove(Float2 mousePos)
|
||||||
|
{
|
||||||
|
if (_dragSourceWindow != null)
|
||||||
|
_toMove.Window.Window.Position = mousePos - _dragOffset;
|
||||||
|
|
||||||
|
UpdateRects(mousePos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user