100 Commits

Author SHA1 Message Date
a45aa74aca Revert "Build Editor bindings only when generating editor project files"
This reverts commit 55ad5ae367.
2025-03-18 01:16:53 +02:00
dbf5dd9e92 _sdl binary 2025-03-07 16:45:33 +02:00
b0ae2b4cd2 Update SDL3 to 3.2.6 2025-03-07 16:45:28 +02:00
ed8001ff8b Fix missing NETX_0_OR_GREATER definitions for previous versions 2025-02-26 22:37:18 +02:00
6e2ed2bdbd Fix TypeDescriptor hack for latest runtime versions 2025-02-26 22:07:29 +02:00
ba88bf8b0f Merge branch 'unload_alc_fix' into wip
# Conflicts:
#	Source/Editor/Modules/WindowsModule.cs
2025-02-26 20:31:07 +02:00
Wojtek Figat
56b2c96b3b Fix missing content database load when opening project without code compilation
#2469
2025-02-26 20:29:44 +02:00
Wojtek Figat
5c06d413b0 Add code sharing
#2469
2025-02-26 20:29:36 +02:00
1c17b77d1e Refocus editor after restoring windows 2025-02-26 20:29:23 +02:00
e24bb71e91 Fix stack overflow when restoring tab in floating window 2025-02-26 20:29:22 +02:00
3382aabefe Close and restore AssetEditorWindows on scripting reload 2025-02-26 20:29:22 +02:00
4ddc765ee4 Fix ContentDatabase not being loaded at the end of editor initialization 2025-02-26 20:29:21 +02:00
5fd64ead62 Fix custom content and importers blocking scripting reload 2025-02-26 20:29:21 +02:00
30257929e5 Fix error when ContentDatabase gets rebuilt while initializing editor 2025-02-26 20:29:21 +02:00
980a112c57 Clear VisjectSurface node caches and context menus during scripts reload 2025-02-26 20:29:20 +02:00
98bbcbd442 Close and restore Prefab windows during scripting reload 2025-02-26 20:29:20 +02:00
9f8faf4f17 Clear references holding on to types in game assemblies 2025-02-26 20:29:19 +02:00
691b9458ec Fix wrong prefab event unregistration 2025-02-26 20:29:19 +02:00
b095acd4a5 Fix scripting AssemblyLoadContext not getting unloaded 2025-02-26 20:29:19 +02:00
afbb8225d8 Avoid showing tooltips in inactive windows 2025-02-26 20:09:32 +02:00
35678b06a8 Merge branch 'api_macro_consistency' into signalgame2 2025-02-26 20:09:31 +02:00
96d39ecb30 _xaudio2 2025-02-26 20:09:31 +02:00
2c7b11a691 Remove texturereferences in default materials 2025-02-26 20:09:30 +02:00
83c288d739 Disable LFS override 2025-02-26 20:09:30 +02:00
8c6b853ee5 Update to enet 2.3.6 2025-02-26 20:09:29 +02:00
b414d7d026 Merge branch 'fixed_update_deltatime' into signalgame2 2025-02-26 20:09:28 +02:00
ae6ec809b8 Merge branch 'richtextbox_optimize' into signalgame2 2025-02-26 20:09:28 +02:00
f47214ae0a Merge branch 'unload_alc_fix' into signalgame2 2025-02-26 20:09:27 +02:00
bddd1b0984 Merge branch 'sdl_platform' into signalgame2 2025-02-26 20:09:27 +02:00
e2e77385b1 Fix missing semicolons 2025-02-26 20:09:26 +02:00
f4c13032a2 Require semicolon after most engine API macros
# Conflicts:
#	Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp
2025-02-26 20:09:26 +02:00
43801d0824 Always run fixed update ticks at fixed deltatime
The random variance in fixed updates makes it impossible to do anything deterministic during physics ticks.
2025-02-26 20:09:25 +02:00
16cd027bf3 Optimize RichTextBox rendering with long text 2025-02-26 20:09:25 +02:00
f361c4bbdb Refocus editor after restoring windows 2025-02-26 20:09:24 +02:00
c4f5777536 Fix stack overflow when restoring tab in floating window 2025-02-26 20:09:24 +02:00
c740d27b0e Close and restore AssetEditorWindows on scripting reload 2025-02-26 20:09:23 +02:00
800b163de9 Fix ContentDatabase not being loaded at the end of editor initialization 2025-02-26 20:09:22 +02:00
7f317d0fb6 Fix custom content and importers blocking scripting reload 2025-02-26 20:09:22 +02:00
714cdd84ad Fix error when ContentDatabase gets rebuilt while initializing editor 2025-02-26 20:09:22 +02:00
26b5172aea Clear VisjectSurface node caches and context menus during scripts reload 2025-02-26 20:09:21 +02:00
47b95f5650 Close and restore Prefab windows during scripting reload 2025-02-26 20:09:21 +02:00
989a5441f3 Clear references holding on to types in game assemblies 2025-02-26 20:09:20 +02:00
6394a7aae0 Fix wrong prefab event unregistration 2025-02-26 20:09:19 +02:00
beff9d5241 Fix scripting AssemblyLoadContext not getting unloaded 2025-02-26 20:09:19 +02:00
16be2fc857 Update SDL3 to 3.2.4 2025-02-13 18:05:09 +02:00
561239a4b2 Fix window dragging when not supported by Wayland compositor
(cherry picked from commit 3554747a67)
2025-02-02 18:38:06 +02:00
389b2e6148 Show current display server in Editor window tooltip
(cherry picked from commit 62968dd437)
2025-02-02 18:38:06 +02:00
9403b87788 Properly mark floating windows with transparency support
(cherry picked from commit c660fac524)
2025-02-02 18:38:06 +02:00
64cceac913 Enable transparency support in Vulkan swapchains
(cherry picked from commit 431a69e357)
2025-02-02 18:38:06 +02:00
c523079f0e Fix compilation for game builds
(cherry picked from commit f4fcc07288)
2025-02-02 18:38:06 +02:00
942124fdc3 Fix cloning SDL repository 2025-01-28 22:24:21 +02:00
9085874d4e Fix text input not working on X11 2025-01-28 22:10:46 +02:00
2f5562f8eb Fix button latching on Windows after drag and drop operation 2025-01-28 22:10:45 +02:00
6733e45729 Implement new window dragging system 2025-01-28 22:10:44 +02:00
37438afbf6 Fix mouse resetting issues after ending relative mode 2025-01-28 22:10:44 +02:00
7c34b1c855 Fix frame stutter when window is focused 2025-01-28 22:10:43 +02:00
3dc2e55627 Fix error when docking to sides of tabbed panel 2025-01-28 22:10:43 +02:00
c658dd72e7 Cleanup Linux SDL implementation 2025-01-28 22:10:43 +02:00
5b8c81dfac Support compiling third party library C files as C code 2025-01-28 22:10:42 +02:00
bf4ec5f91a Implement Wayland protocols module and file generation 2025-01-28 22:10:42 +02:00
15024b38b9 Fix mouse warping after ending relative mode 2025-01-28 22:10:42 +02:00
71ec415cc4 Add git fetch method for dependencies 2025-01-28 22:10:41 +02:00
81b6f47d8a Fix window ShowInTaskbar setting 2025-01-28 22:10:41 +02:00
e55fd18771 Fix various issues with child window positioning 2025-01-28 22:10:41 +02:00
fd97c2bdf2 Add Window.IsAlwaysOnTop property 2025-01-28 22:10:40 +02:00
6ca71a872d Use SDL locale 2025-01-28 22:10:40 +02:00
18e92425bb Allow window with single tab to be dragged from tab area 2025-01-28 22:10:40 +02:00
3feebe8910 Fix ValueBox mouse position resetting after releasing the button 2025-01-28 22:10:39 +02:00
9fc7fc7a2e Fix SDL build process on Linux 2025-01-28 22:10:39 +02:00
642d90a293 Update SDL to 3.2.0 2025-01-28 22:10:39 +02:00
f5313b9ffd Force cursor to center of Game Window when tab handle is clicked 2025-01-28 22:10:38 +02:00
Chandler Cox
7abed39473 Fix rotation using SDL 2025-01-28 22:10:38 +02:00
ffc40ba634 Fix Linux compilation without SDL 2025-01-28 22:09:14 +02:00
84f3cda190 Fix compilation 2025-01-28 22:09:14 +02:00
0f20f387fc Update SDL3 2025-01-28 22:09:13 +02:00
67093a0d28 Fix compilation issues 2025-01-28 22:09:13 +02:00
63eaf1adf2 Fix windows not being hidden initially 2025-01-28 22:09:13 +02:00
28d167b4f8 Fix parent window position handling with popup/tooltip windows 2025-01-28 22:09:12 +02:00
7bff09eeb9 Fix compilation errors in other platforms 2025-01-28 22:09:12 +02:00
5afde966ef Fix CI for Linux 2025-01-28 22:09:12 +02:00
5df1f32305 Prevent building with SDL in unsupported platforms 2025-01-28 22:09:11 +02:00
670f2ee2b0 Fallback to X11 message box implementation when SDL fails 2025-01-28 22:09:11 +02:00
5abf336696 Fix popup and context menus not working on Wayland 2025-01-28 22:09:11 +02:00
7ae0a65c0e Hide warnings for unsupported SDL operations on Wayland 2025-01-28 22:09:10 +02:00
9e88233957 Log a warning for not implemented Wayland functionality 2025-01-28 22:09:10 +02:00
d0a4213538 Fix compilation in Linux 2025-01-28 22:09:10 +02:00
b2467edc0f Enable warning sound in question dialogs 2025-01-28 22:09:09 +02:00
94e398a6b3 Enable modern Windows dialog boxes 2025-01-28 22:09:09 +02:00
e5ca67618f Implement relative mouse mode (raw input) for SDL platform 2025-01-28 22:09:09 +02:00
2da908d9b8 Add flag for Window types 2025-01-28 22:09:09 +02:00
34f187161c Enable native windowing system settings with SDL platform 2025-01-28 22:09:08 +02:00
0e5e0169bf Add command-line switches to force X11 and Wayland SDL drivers 2025-01-28 22:09:08 +02:00
f318d3aadc Implement SDL platform, windowing and input handling 2025-01-28 22:09:08 +02:00
43e38df8b0 Refactor application window class name 2025-01-28 22:09:07 +02:00
86b999f6a4 Move Window related enums to separate header file 2025-01-28 22:09:07 +02:00
553ca7d71c Refactor Windows drag and drop implementation 2025-01-28 22:09:06 +02:00
2594cc4546 Refactor ScreenUtilities 2025-01-28 22:09:06 +02:00
2cd03eceaa Add more helper methods for managing Git repos 2025-01-28 22:09:06 +02:00
d8feec325a Fix centered window location on X11 2025-01-28 22:09:05 +02:00
71b7f110e6 Fix initial position of Tooltips 2025-01-28 22:09:05 +02:00
710 changed files with 16934 additions and 22197 deletions

View File

@@ -73,11 +73,8 @@ jobs:
.\Development\Scripts\Windows\CallBuildTool.bat -build -log -dotnet=8 -arch=x64 -platform=Windows -configuration=Development -buildtargets=FlaxTestsTarget
dotnet msbuild Source\Tools\Flax.Build.Tests\Flax.Build.Tests.csproj /m /t:Restore,Build /p:Configuration=Debug /p:Platform=AnyCPU /nologo
- name: Test
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
.\Binaries\Editor\Win64\Development\FlaxTests.exe
if(!$?) { Write-Host "Tests failed with exit code $LastExitCode" -ForegroundColor Red; Exit $LastExitCode }
dotnet test -f net8.0 Binaries\Tests\Flax.Build.Tests.dll
xcopy /y Binaries\Editor\Win64\Development\FlaxEngine.CSharp.dll Binaries\Tests
xcopy /y Binaries\Editor\Win64\Development\FlaxEngine.CSharp.runtimeconfig.json Binaries\Tests

View File

@@ -1,4 +1,4 @@
# Redirect to our own Git LFS server
[lfs]
url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
locksverify = false
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
locksverify = false

BIN
Content/Editor/Camera/M_Camera.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Camera/O_Camera.flax (Stored with Git LFS)

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/Editor/DefaultFontMaterial.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/Gizmo/Material.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialWire.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/Gizmo/RotationAxis.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Gizmo/ScaleAxis.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/Gizmo/TranslationAxis.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/Gizmo/WireBox.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Highlight Material.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/AudioListener.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/AudioSource.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/Decal.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/DirectionalLight.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/EnvironmentProbe.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/IconsMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/ParticleEffect.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/PointLight.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/Icons/SkyLight.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Icons/Skybox.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

View File

@@ -83,12 +83,6 @@ float3 GetObjectSize(MaterialInput input)
return float3(1, 1, 1);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{

View File

@@ -207,20 +207,6 @@ float3 GetObjectSize(MaterialInput input)
return GeometrySize * float3(world._m00, world._m11, world._m22);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
float4x4 world = WorldMatrix;
// Extract scale from the world matrix
float3 scale;
scale.x = length(float3(world._11, world._12, world._13));
scale.y = length(float3(world._21, world._22, world._23));
scale.z = length(float3(world._31, world._32, world._33));
return scale;
}
// Get the current object random value
float GetPerInstanceRandom(MaterialInput input)
{
@@ -311,7 +297,7 @@ VertexOutput VS_SplineModel(ModelInput input)
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.Geometry.TexCoord = input.TexCoord0;
output.Geometry.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
output.Geometry.VertexColor = input.Color;
#endif

View File

@@ -140,7 +140,7 @@ void SetParticleVec4(uint particleIndex, int offset, float4 value)
bool AddParticle(out uint dstIndex)
{
// Acquire the particle index in the destination buffer
DstParticlesData.InterlockedAdd(ParticleCounterOffset, 1u, dstIndex);
DstParticlesData.InterlockedAdd(ParticleCounterOffset, 1, dstIndex);
// Prevent overflow
return dstIndex >= PARTICLE_CAPACITY;

View File

@@ -163,12 +163,6 @@ float3 GetObjectSize(MaterialInput input)
return float3(1, 1, 1);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{

View File

@@ -299,22 +299,24 @@ half3x3 CalcTangentToLocal(ModelInput input)
float3 normal = input.Normal.xyz * 2.0 - 1.0;
float3 tangent = input.Tangent.xyz * 2.0 - 1.0;
float3 bitangent = cross(normal, tangent) * bitangentSign;
return (half3x3)float3x3(tangent, bitangent, normal);
return float3x3(tangent, bitangent, normal);
}
half3x3 CalcTangentToWorld(in float4x4 world, in half3x3 tangentToLocal)
{
half3x3 localToWorld = (half3x3)RemoveScaleFromLocalToWorld((float3x3)world);
half3x3 localToWorld = RemoveScaleFromLocalToWorld((float3x3)world);
return mul(tangentToLocal, localToWorld);
}
float3 GetParticlePosition(uint particleIndex)
float3 GetParticlePosition(uint ParticleIndex)
{
return TransformParticlePosition(GetParticleVec3(particleIndex, PositionOffset));
return TransformParticlePosition(GetParticleVec3(ParticleIndex, PositionOffset));
}
// Vertex Shader function for Sprite Rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(POSITION, 0, R32G32_FLOAT, 0, 0, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
{
VertexOutput output;
@@ -405,7 +407,7 @@ VertexOutput VS_Sprite(SpriteInput input, uint particleIndex : SV_InstanceID)
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = half3x3(axisX, axisY, axisZ);
half3x3 tangentToLocal = float3x3(axisX, axisY, axisZ);
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
output.TBN = tangentToWorld;
@@ -514,7 +516,7 @@ VertexOutput VS_Model(ModelInput input, uint particleIndex : SV_InstanceID)
output.Position = mul(float4(output.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.TexCoord = input.TexCoord0;
output.TexCoord = input.TexCoord;
output.ParticleIndex = particleIndex;
#if USE_VERTEX_COLOR
output.VertexColor = input.Color;
@@ -610,7 +612,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
{
output.TexCoord.x = (float)input.Order / (float)RibbonSegmentCount;
}
output.TexCoord.y = (float)((vertexIndex + 1) & 0x1);
output.TexCoord.y = (vertexIndex + 1) & 0x1;
output.TexCoord = output.TexCoord * RibbonUVScale + RibbonUVOffset;
// Compute world space vertex position
@@ -629,7 +631,7 @@ VertexOutput VS_Ribbon(RibbonInput input, uint vertexIndex : SV_VertexID)
output.InstanceParams = PerInstanceRandom;
// Calculate tanget space to world space transformation matrix for unit vectors
half3x3 tangentToLocal = half3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
half3x3 tangentToLocal = float3x3(tangentRight, tangentUp, cross(tangentRight, tangentUp));
half3x3 tangentToWorld = CalcTangentToWorld(world, tangentToLocal);
output.TBN = tangentToWorld;

View File

@@ -2,7 +2,6 @@
// Version: @0
#define MATERIAL 1
#define MATERIAL_TEXCOORDS 4
#define USE_PER_VIEW_CONSTANTS 1
#define USE_PER_DRAW_CONSTANTS 1
@3
@@ -25,29 +24,21 @@ Buffer<float4> BoneMatrices : register(t1);
Buffer<float4> PrevBoneMatrices : register(t2);
#endif
#endif
// Geometry data passed though the graphics rendering stages up to the pixel shader
struct GeometryData
{
float3 WorldPosition : TEXCOORD0;
float4 TexCoords01 : TEXCOORD1;
float4 TexCoords23 : TEXCOORD2;
float2 LightmapUV : TEXCOORD3;
float2 TexCoord : TEXCOORD1;
float2 LightmapUV : TEXCOORD2;
#if USE_VERTEX_COLOR
half4 VertexColor : COLOR;
#endif
float3 WorldNormal : TEXCOORD4;
float4 WorldTangent : TEXCOORD5;
float3 WorldNormal : TEXCOORD3;
float4 WorldTangent : TEXCOORD4;
float3 PrevWorldPosition : TEXCOORD7;
nointerpolation uint ObjectIndex : TEXCOORD8;
};
float3 DecodeNormal(float4 normalMap)
{
float2 xy = normalMap.rg * 2.0 - 1.0;
return float3(xy, sqrt(1.0 - saturate(dot(xy, xy))));
}
// Interpolants passed from the vertex shader
struct VertexOutput
{
@@ -77,7 +68,7 @@ struct MaterialInput
{
float3 WorldPosition;
float TwoSidedSign;
float2 TexCoords[MATERIAL_TEXCOORDS];
float2 TexCoord;
#if USE_LIGHTMAP
float2 LightmapUV;
#endif
@@ -95,18 +86,12 @@ struct MaterialInput
#endif
};
// Map access to the main texure coordinate channel as UV0
#define TexCoord TexCoords[0]
// Extracts geometry data to the material input
MaterialInput GetGeometryMaterialInput(GeometryData geometry)
{
MaterialInput output = (MaterialInput)0;
output.WorldPosition = geometry.WorldPosition;
output.TexCoords[0] = geometry.TexCoords01.xy;
output.TexCoords[1] = geometry.TexCoords01.zw;
output.TexCoords[2] = geometry.TexCoords23.xy;
output.TexCoords[3] = geometry.TexCoords23.zw;
output.TexCoord = geometry.TexCoord;
#if USE_LIGHTMAP
output.LightmapUV = geometry.LightmapUV;
#endif
@@ -141,8 +126,8 @@ MaterialInput GetGeometryMaterialInput(GeometryData geometry)
GeometryData InterpolateGeometry(GeometryData p0, float w0, GeometryData p1, float w1, GeometryData p2, float w2)
{
GeometryData output = (GeometryData)0;
output.TexCoords01 = p0.TexCoords01 * w0 + p1.TexCoords01 * w1 + p2.TexCoords01 * w2;
output.TexCoords23 = p0.TexCoords23 * w0 + p1.TexCoords23 * w1 + p2.TexCoords23 * w2;
output.TexCoord = p0.TexCoord * w0 + p1.TexCoord * w1 + p2.TexCoord * w2;
output.LightmapUV = p0.LightmapUV * w0 + p1.LightmapUV * w1 + p2.LightmapUV * w2;
#if USE_VERTEX_COLOR
output.VertexColor = p0.VertexColor * w0 + p1.VertexColor * w1 + p2.VertexColor * w2;
#endif
@@ -238,24 +223,6 @@ float3 GetObjectSize(MaterialInput input)
return input.Object.GeometrySize * float3(world._m00, world._m11, world._m22);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
float4x4 world = input.Object.WorldMatrix;
// Get the squares of the scale factors
float scaleXSquared = dot(world[0].xyz, world[0].xyz);
float scaleYSquared = dot(world[1].xyz, world[1].xyz);
float scaleZSquared = dot(world[2].xyz, world[2].xyz);
// Take square root to get actual scales
return float3(
sqrt(scaleXSquared),
sqrt(scaleYSquared),
sqrt(scaleZSquared)
);
}
// Get the current object random value (supports instancing)
float GetPerInstanceRandom(MaterialInput input)
{
@@ -345,15 +312,14 @@ VertexOutput VS(ModelInput input)
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
output.Geometry.TexCoords23 = float4(input.TexCoord2, input.TexCoord3);
output.Geometry.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
output.Geometry.VertexColor = input.Color;
#endif
#if CAN_USE_LIGHTMAP
output.Geometry.LightmapUV = input.LightmapUV * object.LightmapArea.zw + object.LightmapArea.xy;
#else
output.Geometry.LightmapUV = float2(0, 0);
output.Geometry.LightmapUV = input.LightmapUV;
#endif
// Calculate tanget space to world space transformation matrix for unit vectors
@@ -493,7 +459,7 @@ META_VS_IN_ELEMENT(TEXCOORD, 0, R16G16_FLOAT, 0, ALIGN, PER_VERTEX, 0,
META_VS_IN_ELEMENT(NORMAL, 0, R10G10B10A2_UNORM, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TANGENT, 0, R10G10B10A2_UNORM, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(BLENDINDICES, 0, R8G8B8A8_UINT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(BLENDWEIGHTS, 0, R16G16B16A16_FLOAT,0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(BLENDWEIGHT, 0, R16G16B16A16_FLOAT,0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS_Skinned(ModelInput_Skinned input)
{
VertexOutput output;
@@ -520,10 +486,9 @@ VertexOutput VS_Skinned(ModelInput_Skinned input)
output.Position = mul(float4(output.Geometry.WorldPosition, 1), ViewProjectionMatrix);
// Pass vertex attributes
output.Geometry.TexCoords01 = float4(input.TexCoord0, input.TexCoord1);
output.Geometry.TexCoords23 = float4(input.TexCoord2, input.TexCoord3);
output.Geometry.TexCoord = input.TexCoord;
#if USE_VERTEX_COLOR
output.Geometry.VertexColor = input.Color;
output.Geometry.VertexColor = float4(0, 0, 0, 1);
#endif
output.Geometry.LightmapUV = float2(0, 0);

View File

@@ -236,12 +236,6 @@ float3 GetObjectSize(MaterialInput input)
return float3(1, 1, 1);
}
// Gets the current object scale (supports instancing)
float3 GetObjectScale(MaterialInput input)
{
return float3(1, 1, 1);
}
// Get the current object random value
float GetPerInstanceRandom(MaterialInput input)
{
@@ -325,6 +319,8 @@ struct TerrainVertexInput
// Vertex Shader function for terrain rendering
META_VS(true, FEATURE_LEVEL_ES2)
META_VS_IN_ELEMENT(TEXCOORD, 0, R32G32_FLOAT, 0, ALIGN, PER_VERTEX, 0, true)
META_VS_IN_ELEMENT(TEXCOORD, 1, R8G8B8A8_UNORM, 0, ALIGN, PER_VERTEX, 0, true)
VertexOutput VS(TerrainVertexInput input)
{
VertexOutput output;

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/Primitives/Capsule.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Primitives/Cone.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Primitives/Cube.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Primitives/Cylinder.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Primitives/Plane.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Primitives/Sphere.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/SpriteMaterial.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Editor/TexturePreviewMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Wires Debug Material.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Engine/DefaultMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/DefaultRadialMenu.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/DefaultTerrainMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/Models/Box.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/Models/Quad.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/Models/SimpleBox.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/Models/Sphere.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/Models/SphereLowPoly.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/SingleColorMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/SkyboxMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Engine/WhiteMaterial.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/BakeLightmap.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/Editor/Grid.flax (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Shaders/GI/GlobalSurfaceAtlas.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/PostProcessing.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/Quad.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Shaders/Shadows.flax (Stored with Git LFS)

Binary file not shown.

View File

@@ -2,9 +2,9 @@
"Name": "Flax",
"Version": {
"Major": 1,
"Minor": 10,
"Minor": 9,
"Revision": 0,
"Build": 6702
"Build": 6606
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",

View File

@@ -237,7 +237,6 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/GrammarAndSpelling/GrammarChecking/Exceptions/=Try_0020to_0020scripting/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/GrammarAndSpelling/GrammarChecking/RulesStates/=LanguageTool_002EEN_002EE_005FG/@EntryIndexedValue">DisabledByUser</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=EEA05B0ED8200E4BA9D2D3F1052EBFFD/Color/@EntryValue">Blue</s:String>

View File

@@ -15,7 +15,7 @@ if errorlevel 1 goto BuildToolFailed
:: Build bindings for all editor configurations
echo Building C# bindings...
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor,FlaxGame
popd
echo Done!

View File

@@ -14,4 +14,4 @@ bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
# Build bindings for all editor configurations
echo Building C# bindings...
# TODO: Detect the correct architecture here
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor,FlaxGame

View File

@@ -14,4 +14,4 @@ bash ./Development/Scripts/Linux/CallBuildTool.sh --genproject "$@"
# Build bindings for all editor configurations
echo Building C# bindings...
# TODO: Detect the correct architecture here
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor,FlaxGame

View File

@@ -8,7 +8,6 @@
#include "Engine/Core/Math/Color32.h"
#include "Engine/Core/Config/GameSettings.h"
#include "Editor/Utilities/EditorUtilities.h"
#include "Engine/Graphics/PixelFormatSampler.h"
#include "Engine/Graphics/Textures/TextureData.h"
#include "Engine/Tools/TextureTool/TextureTool.h"
#include "Engine/Content/Content.h"
@@ -241,7 +240,7 @@ void UpdateIconData(uint8* iconData, const TextureData* icon)
const TextureMipData* srcPixels = icon->GetData(0, srcPixelsMip);
const Color32* srcPixelsData = (Color32*)srcPixels->Data.Get();
const Int2 srcPixelsSize(Math::Max(1, icon->Width >> srcPixelsMip), Math::Max(1, icon->Height >> srcPixelsMip));
const auto sampler = PixelFormatSampler::Get(icon->Format);
const auto sampler = TextureTool::GetSampler(icon->Format);
ASSERT_LOW_LAYER(sampler);
// Write colors
@@ -253,7 +252,7 @@ void UpdateIconData(uint8* iconData, const TextureData* icon)
for (uint32 x = 0; x < width; x++)
{
float u = (float)x / width;
const Color c = sampler->SampleLinear(srcPixelsData, Float2(u, v), srcPixelsSize, srcPixels->RowPitch);
const Color c = TextureTool::SampleLinear(sampler, Float2(u, v), srcPixelsData, srcPixelsSize, srcPixels->RowPitch);
colorData[idx++] = Color32(c).GetAsBGRA();
}
}
@@ -272,7 +271,7 @@ void UpdateIconData(uint8* iconData, const TextureData* icon)
{
uint32 x = packedX * 8 + pixelIdx;
float u = (float)x / width;
const Color c = sampler->SampleLinear(srcPixelsData, Float2(u, v), srcPixelsSize, srcPixels->RowPitch);
const Color c = TextureTool::SampleLinear(sampler, Float2(u, v), srcPixelsData, srcPixelsSize, srcPixels->RowPitch);
if (c.A < 0.25f)
mask |= 1 << (7 - pixelIdx);
}
@@ -323,7 +322,7 @@ bool UpdateExeIcon(const String& path, const TextureData& icon)
const TextureData* iconRGBA8 = &icon;
TextureData tmpData1;
//if (icon.Format != PixelFormat::R8G8B8A8_UNorm)
if (PixelFormatSampler::Get(icon.Format) == nullptr)
if (TextureTool::GetSampler(icon.Format) == nullptr)
{
if (TextureTool::Convert(tmpData1, *iconRGBA8, PixelFormat::R8G8B8A8_UNorm))
{

View File

@@ -137,7 +137,10 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
if (!FileSystem::DirectoryExists(CacheFolder))
FileSystem::CreateDirectory(CacheFolder);
if (!FileSystem::FileExists(HeaderFilePath))
{
LOG(Warning, "Missing incremental build cooking assets cache.");
return;
}
auto file = FileReadStream::Open(HeaderFilePath);
if (file == nullptr)
@@ -155,7 +158,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
LOG(Info, "Loading incremental build cooking cache (entries count: {0})", entriesCount);
file->ReadBytes(&Settings, sizeof(Settings));
Entries.EnsureCapacity(entriesCount);
Entries.EnsureCapacity(Math::RoundUpToPowerOf2(static_cast<int32>(entriesCount * 3.0f)));
Array<Pair<String, DateTime>> fileDependencies;
for (int32 i = 0; i < entriesCount; i++)
@@ -163,7 +166,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
Guid id;
file->Read(id);
String typeName;
file->Read(typeName);
file->ReadString(&typeName);
DateTime fileModified;
file->Read(fileModified);
int32 fileDependenciesCount;
@@ -173,7 +176,7 @@ void CookAssetsStep::CacheData::Load(CookingData& data)
for (int32 j = 0; j < fileDependenciesCount; j++)
{
Pair<String, DateTime>& f = fileDependencies[j];
file->Read(f.First, 10);
file->ReadString(&f.First, 10);
file->Read(f.Second);
}
@@ -308,9 +311,9 @@ void CookAssetsStep::CacheData::Save(CookingData& data)
{
auto& e = i->Value;
file->Write(e.ID);
file->Write(e.TypeName);
file->WriteString(e.TypeName);
file->Write(e.FileModified);
file->Write(e.FileDependencies.Count());
file->WriteInt32(e.FileDependencies.Count());
for (auto& f : e.FileDependencies)
{
file->Write(f.First, 10);
@@ -362,27 +365,17 @@ bool CookAssetsStep::ProcessDefaultAsset(AssetCookData& options)
bool CookAssetsStep::Process(CookingData& data, CacheData& cache, Asset* asset)
{
PROFILE_CPU_ASSET(asset);
// Validate asset
if (asset->IsVirtual())
{
// Virtual assets are not included into the build
return false;
}
const bool wasLoaded = asset->IsLoaded();
if (asset->WaitForLoaded())
{
LOG(Error, "Failed to load asset \'{0}\'", asset->ToString());
return true;
}
if (!wasLoaded)
{
// HACK: give some time to resave any old assets in Asset::onLoad after it's loaded
// This assumes that if Load Thread enters Asset::Save then it will get asset lock and hold it until asset is saved
// So we can take the same lock to wait for save end but first we need to wait for it to get that lock
// (in future try to handle it in a better way)
Platform::Sleep(5);
}
ScopeLock lock(asset->Locker);
// Switch based on an asset type
const auto asBinaryAsset = dynamic_cast<BinaryAsset*>(asset);
@@ -800,10 +793,7 @@ bool CookAssetsStep::Process(CookingData& data, CacheData& cache, BinaryAsset* a
// Prepare asset data
AssetInitData initData;
if (asset->Storage->LoadAssetHeader(asset->GetID(), initData))
{
LOG(Warning, "Failed to load asset {} header from storage '{}'", asset->GetID(), asset->Storage->GetPath());
return true;
}
initData.Header.UnlinkChunks();
initData.Metadata.Release();
for (auto& e : initData.Dependencies)
@@ -1175,7 +1165,7 @@ bool CookAssetsStep::Perform(CookingData& data)
assetRef = Content::LoadAsync<Asset>(assetId);
if (assetRef == nullptr)
{
LOG(Error, "Failed to load asset {} included in build", assetId);
data.Error(TEXT("Failed to load asset included in build."));
return true;
}
e.Info.TypeName = assetRef->GetTypeName();
@@ -1183,7 +1173,6 @@ bool CookAssetsStep::Perform(CookingData& data)
// Cook asset
if (Process(data, cache, assetRef.Get()))
{
LOG(Error, "Failed to process asset {}", assetRef->ToString());
cache.Save(data);
return true;
}
@@ -1216,17 +1205,10 @@ bool CookAssetsStep::Perform(CookingData& data)
// Copy file
if (!FileSystem::FileExists(cookedPath) || FileSystem::GetFileLastEditTime(cookedPath) >= FileSystem::GetFileLastEditTime(filePath))
{
const String cookedFolder = StringUtils::GetDirectoryName(cookedPath);
if (FileSystem::CreateDirectory(cookedFolder))
{
LOG(Error, "Failed to create directory '{}'", cookedFolder);
if (FileSystem::CreateDirectory(StringUtils::GetDirectoryName(cookedPath)))
return true;
}
if (FileSystem::CopyFile(cookedPath, filePath))
{
LOG(Error, "Failed to copy file from '{}' to '{}'", filePath, cookedPath);
return true;
}
}
// Count stats of file extension
@@ -1267,7 +1249,7 @@ bool CookAssetsStep::Perform(CookingData& data)
*(int32*)(bytes.Get() + 804) = contentKey;
*(Guid*)(bytes.Get() + 808) = gameSettings->SplashScreen;
Encryption::EncryptBytes(bytes.Get(), bytes.Count());
stream->Write(bytes);
stream->WriteArray(bytes);
Delete(stream);
}
@@ -1295,6 +1277,8 @@ bool CookAssetsStep::Perform(CookingData& data)
assetStats.Count++;
assetStats.ContentSize += FileSystem::GetFileSize(cookedFilePath);
LOG(Info, "Cooked size of {0}: {1}KB", assetId, (FileSystem::GetFileSize(cookedFilePath) / (1024)));
if (packageBuilder.Add(data, i->Value, cookedFilePath))
return true;
}

View File

@@ -213,59 +213,38 @@ bool DeployDataStep::Perform(CookingData& data)
}
FileSystem::NormalizePath(srcDotnet);
LOG(Info, "Using .NET Runtime {} at {}", TEXT("Host"), srcDotnet);
const bool srcDotnetFromEngine = srcDotnet.Contains(TEXT("Source/Platforms"));
String packFolder = srcDotnet / TEXT("../../../");
// Get .NET runtime version
// Get major Version
Array<String> pathParts;
srcDotnet.Split('/', pathParts);
String version;
for (int i = 0; i < pathParts.Count(); i++)
{
// Detect from path provided by build tool
Array<String> pathParts;
srcDotnet.Split('/', pathParts);
for (int32 i = 1; i < pathParts.Count(); i++)
if (pathParts[i] == TEXT("runtimes"))
{
if (pathParts[i] == TEXT("runtimes"))
Array<String> versionParts;
pathParts[i - 1].Split('.', versionParts);
if (!versionParts.IsEmpty())
{
Array<String> versionParts;
pathParts[i - 1].Split('.', versionParts);
if (!versionParts.IsEmpty())
{
const String majorVersion = versionParts[0].TrimTrailing();
int32 versionNum;
StringUtils::Parse(*majorVersion, majorVersion.Length(), &versionNum);
if (Math::IsInRange(versionNum, GAME_BUILD_DOTNET_RUNTIME_MIN_VER, GAME_BUILD_DOTNET_RUNTIME_MAX_VER)) // Check for major part
version = majorVersion;
}
}
}
if (version.IsEmpty())
{
if (srcDotnetFromEngine)
{
// Detect version from runtime files inside Engine Platform folder
for (int32 i = GAME_BUILD_DOTNET_RUNTIME_MAX_VER; i >= GAME_BUILD_DOTNET_RUNTIME_MIN_VER; i--)
{
// Check runtime files inside Engine Platform folder
String testPath1 = srcDotnet / String::Format(TEXT("lib/net{}.0"), i);
String testPath2 = packFolder / String::Format(TEXT("Dotnet/lib/net{}.0"), i);
if ((FileSystem::DirectoryExists(testPath1) && FileSystem::GetDirectorySize(testPath1) > 0) ||
(FileSystem::DirectoryExists(testPath2) && FileSystem::GetDirectorySize(testPath2) > 0))
{
version = StringUtils::ToString(i);
break;
}
}
}
if (version.IsEmpty())
{
data.Error(TEXT("Failed to find supported .NET version for the current host platform."));
return true;
const String majorVersion = versionParts[0].TrimTrailing();
int32 versionNum;
StringUtils::Parse(*majorVersion, majorVersion.Length(), &versionNum);
if (Math::IsInRange(versionNum, GAME_BUILD_DOTNET_RUNTIME_MIN_VER, GAME_BUILD_DOTNET_RUNTIME_MAX_VER)) // Check for major part
version = majorVersion;
}
}
}
if (version.IsEmpty())
{
data.Error(TEXT("Failed to find supported .NET version for the current host platform."));
return true;
}
// Deploy runtime files
const Char* corlibPrivateName = TEXT("System.Private.CoreLib.dll");
const bool srcDotnetFromEngine = srcDotnet.Contains(TEXT("Source/Platforms"));
String packFolder = srcDotnet / TEXT("../../../");
String dstDotnetLibs = dstDotnet, srcDotnetLibs = srcDotnet;
StringUtils::PathRemoveRelativeParts(packFolder);
if (usAOT)
@@ -436,9 +415,9 @@ bool DeployDataStep::Perform(CookingData& data)
data.AddRootEngineAsset(TEXT("Engine/Textures/NormalTexture"));
data.AddRootEngineAsset(TEXT("Engine/Textures/BlackTexture"));
data.AddRootEngineAsset(TEXT("Engine/Textures/WhiteTexture"));
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensStarburst"));
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensColor"));
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensDirt"));
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensStarburst"));
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensColor"));
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensDirt"));
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Circle"));
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Hexagon"));
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Octagon"));

View File

@@ -195,6 +195,15 @@ namespace FlaxEditor.CustomEditors
Presenter.AfterLayout?.Invoke(layout);
}
/// <inheritdoc />
protected override void Deinitialize()
{
Editor = null;
_overrideEditor = null;
base.Deinitialize();
}
/// <inheritdoc />
protected override void OnModified()
{

View File

@@ -39,9 +39,14 @@ CustomEditorsUtilService CustomEditorsUtilServiceInstance;
struct Entry
{
MClass* DefaultEditor = nullptr;
MClass* CustomEditor = nullptr;
MType* CustomEditorType = nullptr;
MClass* DefaultEditor;
MClass* CustomEditor;
Entry()
{
DefaultEditor = nullptr;
CustomEditor = nullptr;
}
};
Dictionary<MType*, Entry> Cache(512);
@@ -58,11 +63,11 @@ MTypeObject* CustomEditorsUtil::GetCustomEditor(MTypeObject* refType)
Entry result;
if (Cache.TryGet(type, result))
{
if (result.CustomEditorType)
return INTERNAL_TYPE_GET_OBJECT(result.CustomEditorType);
MClass* editor = result.CustomEditor ? result.CustomEditor : result.DefaultEditor;
if (editor)
{
return MUtils::GetType(editor);
}
}
return nullptr;
}
@@ -152,7 +157,7 @@ void OnAssemblyLoaded(MAssembly* assembly)
else if (typeClass)
{
auto& entry = Cache[mclass->GetType()];
entry.CustomEditorType = type;
entry.CustomEditor = typeClass;
//LOG(Info, "Custom Editor {0} for type {1}", String(typeClass->GetFullName()), String(mclass->GetFullName()));
}

View File

@@ -69,7 +69,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
Values.SetReferenceValue(prefabInstance);
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
prefab.GetNestedObject(ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
var prefabId = prefab.ID;
Editor.GetPrefabNestedObject(ref prefabId, ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId);
var panel = layout.CustomContainer<UniformGridPanel>();
panel.CustomControl.Height = 20.0f;
@@ -205,7 +206,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (_linkedPrefabId != Guid.Empty)
{
_linkedPrefabId = Guid.Empty;
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplying;
Editor.Instance.Prefabs.PrefabApplying -= OnPrefabApplying;
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplied;
}
}

View File

@@ -1057,6 +1057,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
protected override void Deinitialize()
{
_scriptToggles = null;
_scripts.Clear();
base.Deinitialize();
}

View File

@@ -92,7 +92,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
{
if (IsLinearTangentMode(spline, index) || IsSmoothInTangentMode(spline, index) || IsSmoothOutTangentMode(spline, index))
{
SetPointSmooth(Editor, spline, index);
SetPointSmooth(spline, index);
}
}
}
@@ -145,7 +145,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
{
if (!IsAlignedTangentMode(spline, index))
{
SetPointSmooth(Editor, spline, index);
SetPointSmooth(spline, index);
}
}
@@ -176,7 +176,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
/// <inheritdoc/>
public override void OnSetMode(Spline spline, int index)
{
SetTangentSmoothIn(Editor, spline, index);
SetTangentSmoothIn(spline, index);
Editor.SetSelectTangentIn(spline, index);
}
}
@@ -190,7 +190,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
/// <inheritdoc/>
public override void OnSetMode(Spline spline, int index)
{
SetTangentSmoothOut(Editor, spline, index);
SetTangentSmoothOut(spline, index);
Editor.SetSelectTangentOut(spline, index);
}
}
@@ -756,15 +756,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
spline.UpdateSpline();
}
private static void SetTangentSmoothIn(SplineEditor editor, Spline spline, int index)
private static void SetTangentSmoothIn(Spline spline, int index)
{
var keyframe = spline.GetSplineKeyframe(index);
// Auto smooth tangent if's linear
if (keyframe.TangentIn.Translation.Length == 0)
{
var cameraTransform = editor.Presenter.Owner.PresenterViewport.ViewTransform.Translation;
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplineTangent(index, false).Translation, 10f, cameraTransform);
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplineTangent(index, false).Translation, 10f);
var previousKeyframe = spline.GetSplineKeyframe(index - 1);
var tangentDirection = keyframe.Value.WorldToLocalVector(previousKeyframe.Value.Translation - keyframe.Value.Translation);
tangentDirection = tangentDirection.Normalized * smoothRange;
@@ -776,15 +775,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
spline.UpdateSpline();
}
private static void SetTangentSmoothOut(SplineEditor editor, Spline spline, int index)
private static void SetTangentSmoothOut(Spline spline, int index)
{
var keyframe = spline.GetSplineKeyframe(index);
// Auto smooth tangent if's linear
if (keyframe.TangentOut.Translation.Length == 0)
{
var cameraTransform = editor.Presenter.Owner.PresenterViewport.ViewTransform.Translation;
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplineTangent(index, false).Translation, 10f, cameraTransform);
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplineTangent(index, false).Translation, 10f);
var nextKeyframe = spline.GetSplineKeyframe(index + 1);
var tangentDirection = keyframe.Value.WorldToLocalVector(nextKeyframe.Value.Translation - keyframe.Value.Translation);
tangentDirection = tangentDirection.Normalized * smoothRange;
@@ -797,7 +795,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
spline.UpdateSpline();
}
private static void SetPointSmooth(SplineEditor editor, Spline spline, int index)
private static void SetPointSmooth(Spline spline, int index)
{
var keyframe = spline.GetSplineKeyframe(index);
var tangentInSize = keyframe.TangentIn.Translation.Length;
@@ -805,8 +803,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var isLastKeyframe = index >= spline.SplinePointsCount - 1;
var isFirstKeyframe = index <= 0;
var cameraTransform = editor.Presenter.Owner.PresenterViewport.ViewTransform.Translation;
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplinePoint(index), 10f, cameraTransform);
var smoothRange = SplineNode.NodeSizeByDistance(spline.GetSplinePoint(index), 10f);
// Force smooth it's linear point
if (tangentInSize == 0f)

View File

@@ -95,7 +95,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (assetReference != null)
{
if (assetReference.UseSmallPicker)
height = 36;
height = 32;
if (string.IsNullOrEmpty(assetReference.TypeName))
{
}

View File

@@ -1,84 +0,0 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
using Object = FlaxEngine.Object;
namespace FlaxEditor.CustomEditors.Editors;
/// <summary>
/// The reference picker control used for UIControls using ControlReference.
/// </summary>
internal class UIControlRefPickerControl : FlaxObjectRefPickerControl
{
/// <summary>
/// Type of the control to pick.
/// </summary>
public Type ControlType;
/// <inheritdoc />
protected override bool IsValid(Object obj)
{
return obj == null || (obj is UIControl control && control.Control.GetType() == ControlType);
}
}
/// <summary>
/// ControlReferenceEditor class.
/// </summary>
[CustomEditor(typeof(ControlReference<>)), DefaultEditor]
internal class ControlReferenceEditor : CustomEditor
{
private CustomElement<UIControlRefPickerControl> _element;
/// <inheritdoc />
public override DisplayStyle Style => DisplayStyle.Inline;
/// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout)
{
if (!HasDifferentTypes)
{
_element = layout.Custom<UIControlRefPickerControl>();
if (ValuesTypes == null || ValuesTypes[0] == null)
{
Editor.LogWarning("ControlReference needs to be assigned in code.");
return;
}
Type genType = ValuesTypes[0].GetGenericArguments()[0];
if (typeof(Control).IsAssignableFrom(genType))
{
_element.CustomControl.PresenterContext = Presenter.Owner;
_element.CustomControl.ControlType = genType;
_element.CustomControl.Type = new ScriptType(typeof(UIControl));
}
_element.CustomControl.ValueChanged += () =>
{
Type genericType = ValuesTypes[0].GetGenericArguments()[0];
if (typeof(Control).IsAssignableFrom(genericType))
{
Type t = typeof(ControlReference<>);
Type tw = t.MakeGenericType(new Type[] { genericType });
var instance = Activator.CreateInstance(tw);
((IControlReference)instance).UIControl = (UIControl)_element.CustomControl.Value;
SetValue(instance);
}
};
}
}
/// <inheritdoc />
public override void Refresh()
{
base.Refresh();
if (!HasDifferentValues)
{
if (Values[0] is IControlReference cr)
_element.CustomControl.Value = cr.UIControl;
}
}
}

View File

@@ -48,7 +48,7 @@ namespace FlaxEditor.CustomEditors.Editors
public IPresenterOwner PresenterContext;
/// <summary>
/// Gets or sets the allowed objects type (given type and all subclasses). Must be <see cref="Object"/> type of any subclass.
/// Gets or sets the allowed objects type (given type and all sub classes). Must be <see cref="Object"/> type of any subclass.
/// </summary>
public ScriptType Type
{
@@ -61,8 +61,7 @@ namespace FlaxEditor.CustomEditors.Editors
throw new ArgumentException(string.Format("Invalid type for FlaxObjectRefEditor. Input type: {0}", value != ScriptType.Null ? value.TypeName : "null"));
_type = value;
_supportsPickDropDown = new ScriptType(typeof(Actor)).IsAssignableFrom(value) ||
new ScriptType(typeof(Script)).IsAssignableFrom(value);
_supportsPickDropDown = new ScriptType(typeof(Actor)).IsAssignableFrom(value) || new ScriptType(typeof(Script)).IsAssignableFrom(value);
// Deselect value if it's not valid now
if (!IsValid(_value))
@@ -81,7 +80,7 @@ namespace FlaxEditor.CustomEditors.Editors
if (_value == value)
return;
if (!IsValid(value))
value = null;
throw new ArgumentException("Invalid object type.");
// Special case for missing objects (eg. referenced actor in script that is deleted in editor)
if (value != null && (Object.GetUnmanagedPtr(value) == IntPtr.Zero || value.ID == Guid.Empty))
@@ -92,17 +91,27 @@ namespace FlaxEditor.CustomEditors.Editors
// Get name to display
if (_value is Script script)
{
_valueName = script.Actor ? $"{type.Name} ({script.Actor.Name})" : type.Name;
}
else if (_value != null)
{
_valueName = _value.ToString();
}
else
{
_valueName = string.Empty;
}
// Update tooltip
if (_value is SceneObject sceneObject)
{
TooltipText = Utilities.Utils.GetTooltip(sceneObject);
}
else
{
TooltipText = string.Empty;
}
OnValueChanged();
}
@@ -141,12 +150,7 @@ namespace FlaxEditor.CustomEditors.Editors
_type = ScriptType.Object;
}
/// <summary>
/// Object validation check routine.
/// </summary>
/// <param name="obj">Input object to check.</param>
/// <returns>True if it can be assigned, otherwise false.</returns>
protected virtual bool IsValid(Object obj)
private bool IsValid(Object obj)
{
var type = TypeUtils.GetObjectType(obj);
return obj == null || _type.IsAssignableFrom(type) && (CheckValid == null || CheckValid(obj, type));
@@ -164,15 +168,6 @@ namespace FlaxEditor.CustomEditors.Editors
Focus();
}, PresenterContext);
}
else if (new ScriptType(typeof(Control)).IsAssignableFrom(_type))
{
ActorSearchPopup.Show(this, new Float2(0, Height), IsValid, actor =>
{
Value = actor as UIControl;
RootWindow.Focus();
Focus();
}, PresenterContext);
}
else
{
ScriptSearchPopup.Show(this, new Float2(0, Height), IsValid, script =>
@@ -204,7 +199,7 @@ namespace FlaxEditor.CustomEditors.Editors
var frameRect = new Rectangle(0, 0, Width, 16);
if (isSelected)
frameRect.Width -= 16;
if (_supportsPickDropDown && isEnabled)
if (_supportsPickDropDown)
frameRect.Width -= 16;
var nameRect = new Rectangle(2, 1, frameRect.Width - 4, 14);
var button1Rect = new Rectangle(nameRect.Right + 2, 1, 14, 14);
@@ -240,7 +235,7 @@ namespace FlaxEditor.CustomEditors.Editors
}
// Draw picker button
if (_supportsPickDropDown && isEnabled)
if (_supportsPickDropDown)
{
var pickerRect = isSelected ? button2Rect : button1Rect;
Render2D.DrawSprite(style.ArrowDown, pickerRect, isEnabled && pickerRect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
@@ -405,9 +400,20 @@ namespace FlaxEditor.CustomEditors.Editors
// Select object
if (_value is Actor actor)
Select(actor);
{
if (PresenterContext is PropertiesWindow)
Editor.Instance.SceneEditing.Select(actor);
else if (PresenterContext is PrefabWindow prefabWindow)
prefabWindow.Select(prefabWindow.Graph.Root.Find(actor));
}
else if (_value is Script script && script.Actor)
Select(script.Actor);
{
var a = script.Actor;
if (PresenterContext is PropertiesWindow)
Editor.Instance.SceneEditing.Select(a);
else if (PresenterContext is PrefabWindow prefabWindow)
prefabWindow.Select(prefabWindow.Graph.Root.Find(a));
}
else if (_value is Asset asset)
Editor.Instance.Windows.ContentWin.Select(asset);
}
@@ -425,14 +431,6 @@ namespace FlaxEditor.CustomEditors.Editors
ShowDropDownMenu();
}
private void Select(Actor actor)
{
if (PresenterContext is PropertiesWindow)
Editor.Instance.SceneEditing.Select(actor);
else if (PresenterContext is PrefabWindow prefabWindow)
prefabWindow.Select(prefabWindow.Graph.Root.Find(actor));
}
private void DoDrag()
{
// Do the drag drop operation if has selected element

View File

@@ -819,6 +819,15 @@ namespace FlaxEditor.CustomEditors.Editors
OnGroupsEnd();
}
/// <inheritdoc />
protected override void Deinitialize()
{
_visibleIfCaches = null;
_visibleIfPropertiesListsCache = null;
base.Deinitialize();
}
/// <inheritdoc />
public override void Refresh()
{

View File

@@ -36,7 +36,7 @@ namespace FlaxEditor.CustomEditors.Editors
float height = 48;
if (assetReference.UseSmallPicker)
height = 36;
height = 32;
if (string.IsNullOrEmpty(assetReference.TypeName))
{

View File

@@ -41,9 +41,6 @@ public class Editor : EditorModule
options.ScriptingAPI.SystemReferences.Add("System.Xml.ReaderWriter");
options.ScriptingAPI.SystemReferences.Add("System.Text.RegularExpressions");
options.ScriptingAPI.SystemReferences.Add("System.IO.Compression.ZipFile");
options.ScriptingAPI.SystemReferences.Add("System.Diagnostics.Process");
if (Profiler.Use(options))
options.ScriptingAPI.Defines.Add("USE_PROFILER");
// Enable optimizations for Editor, disable this for debugging the editor
if (options.Configuration == TargetConfiguration.Development)

View File

@@ -79,6 +79,10 @@ bool Editor::CheckProjectUpgrade()
Delete(file);
}
}
else
{
LOG(Warning, "Missing version cache file");
}
// Check if project is in the old, deprecated layout
if (EditorImpl::IsOldProjectXmlFormat)
@@ -399,7 +403,7 @@ int32 Editor::LoadProduct()
}
// Create new project option
if (CommandLine::Options.NewProject.IsTrue())
if (CommandLine::Options.NewProject)
{
Array<String> projectFiles;
FileSystem::DirectoryGetFiles(projectFiles, projectPath, TEXT("*.flaxproj"), DirectorySearchOption::TopDirectoryOnly);
@@ -424,7 +428,7 @@ int32 Editor::LoadProduct()
}
}
}
if (CommandLine::Options.NewProject.IsTrue())
if (CommandLine::Options.NewProject)
{
if (projectPath.IsEmpty())
projectPath = Platform::GetWorkingDirectory();
@@ -525,7 +529,7 @@ int32 Editor::LoadProduct()
if (projectPath.IsEmpty())
{
#if PLATFORM_HAS_HEADLESS_MODE
if (CommandLine::Options.Headless.IsTrue())
if (CommandLine::Options.Headless)
{
Platform::Fatal(TEXT("Missing project path."));
return -1;
@@ -608,7 +612,7 @@ int32 Editor::LoadProduct()
// Validate project min supported version (older engine may try to load newer project)
// Special check if project specifies only build number, then major/minor fields are set to 0
const auto engineVersion = FLAXENGINE_VERSION;
for (const auto& e : projects)
for (auto e : projects)
{
const auto project = e.Item;
if (project->MinEngineVersion > engineVersion ||
@@ -653,7 +657,7 @@ Window* Editor::CreateMainWindow()
bool Editor::Init()
{
// Scripts project files generation from command line
if (CommandLine::Options.GenProjectFiles.IsTrue())
if (CommandLine::Options.GenProjectFiles)
{
const String customArgs = TEXT("-verbose -log -logfile=\"Cache/Intermediate/ProjectFileLog.txt\"");
const bool failed = ScriptsBuilder::GenerateProject(customArgs);

View File

@@ -1550,9 +1550,9 @@ namespace FlaxEditor
// Handle case when Game window is not selected in tab view
var dockedTo = gameWin.ParentDockPanel;
if (dockedTo != null && dockedTo.SelectedTab != gameWin && dockedTo.SelectedTab != null)
result = dockedTo.SelectedTab.Size;
result = dockedTo.SelectedTab.Size * root.DpiScale;
else
result = gameWin.Viewport.Size;
result = gameWin.Viewport.Size * root.DpiScale;
result = Float2.Round(result);
}

View File

@@ -355,14 +355,14 @@ namespace FlaxEditor.GUI.ContextMenu
}
/// <inheritdoc />
public override void Show(Control parent, Float2 location, ContextMenuDirection? direction = null)
public override void Show(Control parent, Float2 location)
{
// Remove last separator to make context menu look better
int lastIndex = _panel.Children.Count - 1;
if (lastIndex >= 0 && _panel.Children[lastIndex] is ContextMenuSeparator separator)
separator.Dispose();
base.Show(parent, location, direction);
base.Show(parent, location);
}
/// <inheritdoc />

View File

@@ -101,16 +101,6 @@ namespace FlaxEditor.GUI.ContextMenu
/// </summary>
public List<Window> ExternalPopups = new List<Window>();
/// <summary>
/// Optional flag that can disable popup visibility based on window focus and use external control via Hide.
/// </summary>
public bool UseVisibilityControl = true;
/// <summary>
/// Optional flag that can disable popup input capturing. Useful for transparent or visual-only popups.
/// </summary>
public bool UseInput = true;
/// <summary>
/// Initializes a new instance of the <see cref="ContextMenuBase"/> class.
/// </summary>
@@ -147,26 +137,21 @@ namespace FlaxEditor.GUI.ContextMenu
/// </summary>
/// <param name="parent">Parent control to attach to it.</param>
/// <param name="location">Popup menu origin location in parent control coordinates.</param>
/// <param name="direction">The custom popup direction. Null to use automatic direction.</param>
public virtual void Show(Control parent, Float2 location, ContextMenuDirection? direction = null)
public virtual void Show(Control parent, Float2 location)
{
Assert.IsNotNull(parent);
bool isAlreadyVisible = Visible && _window;
if (!isAlreadyVisible)
Hide();
// Ensure to be closed
Hide();
// Peek parent control window
var parentWin = parent.RootWindow;
if (parentWin == null)
{
Hide();
return;
}
// Check if show menu inside the other menu - then link as a child to prevent closing the calling menu window on lost focus
if (_parentCM == null && parentWin.ChildrenCount == 1 && parentWin.Children[0] is ContextMenuBase parentCM)
{
Hide();
parentCM.ShowChild(this, parentCM.PointFromScreen(parent.PointToScreen(location)), false);
return;
}
@@ -184,7 +169,7 @@ namespace FlaxEditor.GUI.ContextMenu
var monitorBounds = Platform.GetMonitorBounds(locationSS);
var rightBottomLocationSS = locationSS + dpiSize;
bool isUp = false, isLeft = false;
if (UseAutomaticDirectionFix && direction == null)
if (UseAutomaticDirectionFix)
{
var parentMenu = parent as ContextMenu;
if (monitorBounds.Bottom < rightBottomLocationSS.Y)
@@ -211,26 +196,6 @@ namespace FlaxEditor.GUI.ContextMenu
locationSS.X -= dpiSize.X;
}
}
else if (direction.HasValue)
{
switch (direction.Value)
{
case ContextMenuDirection.RightUp:
isUp = true;
break;
case ContextMenuDirection.LeftDown:
isLeft = true;
break;
case ContextMenuDirection.LeftUp:
isLeft = true;
isUp = true;
break;
}
if (isLeft)
locationSS.X -= dpiSize.X;
if (isUp)
locationSS.Y -= dpiSize.Y;
}
// Update direction flag
if (isUp)
@@ -238,62 +203,47 @@ namespace FlaxEditor.GUI.ContextMenu
else
_direction = isLeft ? ContextMenuDirection.LeftDown : ContextMenuDirection.RightDown;
if (isAlreadyVisible)
{
_window.ClientBounds = new Rectangle(locationSS, dpiSize);
}
else
{
// Create window
var desc = CreateWindowSettings.Default;
desc.Position = locationSS;
desc.StartPosition = WindowStartPosition.Manual;
desc.Size = dpiSize;
desc.Fullscreen = false;
desc.HasBorder = false;
desc.SupportsTransparency = false;
desc.ShowInTaskbar = false;
desc.ActivateWhenFirstShown = UseInput;
desc.AllowInput = UseInput;
desc.AllowMinimize = false;
desc.AllowMaximize = false;
desc.AllowDragAndDrop = false;
desc.IsTopmost = true;
desc.Type = WindowType.Popup;
desc.Parent = parentWin.Window;
desc.Title = "ContextMenu";
desc.HasSizingFrame = false;
OnWindowCreating(ref desc);
_window = Platform.CreateWindow(ref desc);
if (UseVisibilityControl)
{
_window.GotFocus += OnWindowGotFocus;
_window.LostFocus += OnWindowLostFocus;
}
// Create window
var desc = CreateWindowSettings.Default;
desc.Position = locationSS;
desc.StartPosition = WindowStartPosition.Manual;
desc.Size = dpiSize;
desc.Fullscreen = false;
desc.HasBorder = false;
desc.SupportsTransparency = false;
desc.ShowInTaskbar = false;
desc.ActivateWhenFirstShown = true;
desc.AllowInput = true;
desc.AllowMinimize = false;
desc.AllowMaximize = false;
desc.AllowDragAndDrop = false;
desc.IsTopmost = true;
desc.Type = WindowType.Popup;
desc.Parent = parentWin.Window;
desc.Title = "ContextMenu";
desc.HasSizingFrame = false;
OnWindowCreating(ref desc);
_window = Platform.CreateWindow(ref desc);
_window.GotFocus += OnWindowGotFocus;
_window.LostFocus += OnWindowLostFocus;
#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
parentWin.Window.MouseDown += OnWindowMouseDown;
_window.Closed += () => parentWin.Window.MouseDown -= OnWindowMouseDown;
// The focus between popup and parent windows doesn't change, force hide the popup when clicked on parent
parentWin.Window.MouseDown += OnWindowMouseDown;
_window.Closed += () => parentWin.Window.MouseDown -= OnWindowMouseDown;
#endif
// Attach to the window
_parentCM = parent as ContextMenuBase;
Parent = _window.GUI;
}
// Attach to the window
_parentCM = parent as ContextMenuBase;
Parent = _window.GUI;
// Show
Visible = true;
if (_window == null)
return;
_window.Show();
PerformLayout();
if (UseVisibilityControl)
{
_previouslyFocused = parentWin.FocusedControl;
Focus();
OnShow();
}
_previouslyFocused = parentWin.FocusedControl;
Focus();
OnShow();
}
/// <summary>
@@ -558,7 +508,7 @@ namespace FlaxEditor.GUI.ContextMenu
base.Update(deltaTime);
// Let root context menu to check if none of the popup windows
if (_parentCM == null && UseVisibilityControl && !IsForeground)
if (_parentCM == null && !IsForeground)
{
#if USE_SDL_WORKAROUNDS
if (!IsMouseOver)

View File

@@ -486,7 +486,7 @@ namespace FlaxEditor.GUI.Docking
{
base.Focus();
SelectTab();
SelectTab(false);
BringToFront();
}

View File

@@ -56,11 +56,6 @@ namespace FlaxEditor.GUI
/// </summary>
public event Action<Item> Clicked;
/// <summary>
/// Occurs when items gets focused.
/// </summary>
public event Action<Item> Focused;
/// <summary>
/// The tint color of the text.
/// </summary>
@@ -146,10 +141,6 @@ namespace FlaxEditor.GUI
protected virtual void GetTextRect(out Rectangle rect)
{
rect = new Rectangle(2, 0, Width - 4, Height);
// Indent for drop panel items is handled by drop panel margin
if (Parent is not DropPanel)
rect.Location += new Float2(Editor.Instance.Icons.ArrowRight12.Size.X + 2, 0);
}
/// <inheritdoc />
@@ -164,6 +155,10 @@ namespace FlaxEditor.GUI
if (IsMouseOver || IsFocused)
Render2D.FillRectangle(new Rectangle(Float2.Zero, Size), style.BackgroundHighlighted);
// Indent for drop panel items is handled by drop panel margin
if (Parent is not DropPanel)
textRect.Location += new Float2(Editor.Instance.Icons.ArrowRight12.Size.X + 2, 0);
// Draw all highlights
if (_highlights != null)
{
@@ -212,14 +207,6 @@ namespace FlaxEditor.GUI
base.OnMouseLeave();
}
/// <inheritdoc />
public override void OnGotFocus()
{
base.OnGotFocus();
Focused?.Invoke(this);
}
/// <inheritdoc />
public override int Compare(Control other)
{
@@ -240,7 +227,6 @@ namespace FlaxEditor.GUI
private readonly Panel _scrollPanel;
private List<DropPanel> _categoryPanels;
private bool _waitingForInput;
private string _customSearch;
/// <summary>
/// Event fired when any item in this popup menu gets clicked.
@@ -262,30 +248,26 @@ namespace FlaxEditor.GUI
/// </summary>
/// <param name="width">The control width.</param>
/// <param name="height">The control height.</param>
/// <param name="withSearch">Enables search field.</param>
public ItemsListContextMenu(float width = 320, float height = 220, bool withSearch = true)
public ItemsListContextMenu(float width = 320, float height = 220)
{
// Context menu dimensions
Size = new Float2(width, height);
if (withSearch)
// Search box
_searchBox = new SearchBox(false, 1, 1)
{
// Search box
_searchBox = new SearchBox(false, 1, 1)
{
Parent = this,
Width = Width - 3,
};
_searchBox.TextChanged += OnSearchFilterChanged;
_searchBox.ClearSearchButton.Clicked += () => PerformLayout();
}
Parent = this,
Width = Width - 3,
};
_searchBox.TextChanged += OnSearchFilterChanged;
_searchBox.ClearSearchButton.Clicked += () => PerformLayout();
// Panel with scrollbar
_scrollPanel = new Panel(ScrollBars.Vertical)
{
Parent = this,
AnchorPreset = AnchorPresets.StretchAll,
Bounds = withSearch ? new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - 2) : new Rectangle(Float2.Zero, Size),
Bounds = new Rectangle(0, _searchBox.Bottom + 1, Width, Height - _searchBox.Bottom - 2),
};
// Items list panel
@@ -304,13 +286,12 @@ namespace FlaxEditor.GUI
LockChildrenRecursive();
var searchText = _searchBox?.Text ?? _customSearch;
var items = ItemsPanel.Children;
for (int i = 0; i < items.Count; i++)
{
if (items[i] is Item item)
{
item.UpdateFilter(searchText);
item.UpdateFilter(_searchBox.Text);
item.UpdateScore();
}
}
@@ -324,13 +305,13 @@ namespace FlaxEditor.GUI
{
if (category.Children[j] is Item item2)
{
item2.UpdateFilter(searchText);
item2.UpdateFilter(_searchBox.Text);
item2.UpdateScore();
anyVisible |= item2.Visible;
}
}
category.Visible = anyVisible;
if (string.IsNullOrEmpty(searchText))
if (string.IsNullOrEmpty(_searchBox.Text))
category.Close(false);
else
category.Open(false);
@@ -341,8 +322,8 @@ namespace FlaxEditor.GUI
UnlockChildrenRecursive();
PerformLayout(true);
_searchBox?.Focus();
TextChanged?.Invoke(searchText);
_searchBox.Focus();
TextChanged?.Invoke(_searchBox.Text);
}
/// <summary>
@@ -374,14 +355,6 @@ namespace FlaxEditor.GUI
}
}
/// <summary>
/// Removes all added items.
/// </summary>
public void ClearItems()
{
ItemsPanel.DisposeChildren();
}
/// <summary>
/// Sorts the items list (by item name by default).
/// </summary>
@@ -395,34 +368,6 @@ namespace FlaxEditor.GUI
}
}
/// <summary>
/// Focuses and scroll to the given item to be selected.
/// </summary>
/// <param name="item">The item to select.</param>
public void SelectItem(Item item)
{
item.Focus();
ScrollViewTo(item);
}
/// <summary>
/// Applies custom search text query on the items list. Works even if search field is disabled
/// </summary>
/// <param name="text">The custom search text. Null to clear search.</param>
public void Search(string text)
{
if (_searchBox != null)
{
_searchBox.SetText(text);
}
else
{
_customSearch = text;
if (VisibleInHierarchy)
OnSearchFilterChanged();
}
}
/// <summary>
/// Adds the item to the view and registers for the click event.
/// </summary>
@@ -501,11 +446,9 @@ namespace FlaxEditor.GUI
}
}
_searchBox?.Clear();
_searchBox.Clear();
UnlockChildrenRecursive();
PerformLayout(true);
if (_customSearch != null)
OnSearchFilterChanged();
}
private List<Item> GetVisibleItems()
@@ -567,7 +510,7 @@ namespace FlaxEditor.GUI
if (RootWindow.FocusedControl == null)
{
// Focus search box if nothing is focused
_searchBox?.Focus();
_searchBox.Focus();
return true;
}
@@ -593,7 +536,7 @@ namespace FlaxEditor.GUI
var focusedIndex = items.IndexOf(focusedItem);
if (focusedIndex == 0)
{
_searchBox?.Focus();
_searchBox.Focus();
}
else if (focusedIndex > 0)
{
@@ -613,7 +556,7 @@ namespace FlaxEditor.GUI
break;
}
if (_waitingForInput && _searchBox != null)
if (_waitingForInput)
{
_waitingForInput = false;
_searchBox.Focus();

Some files were not shown because too many files have changed in this diff Show More