Compare commits
213 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a45aa74aca | |||
| dbf5dd9e92 | |||
| b0ae2b4cd2 | |||
| ed8001ff8b | |||
| 6e2ed2bdbd | |||
| ba88bf8b0f | |||
|
|
56b2c96b3b | ||
|
|
5c06d413b0 | ||
| 1c17b77d1e | |||
| e24bb71e91 | |||
| 3382aabefe | |||
| 4ddc765ee4 | |||
| 5fd64ead62 | |||
| 30257929e5 | |||
| 980a112c57 | |||
| 98bbcbd442 | |||
| 9f8faf4f17 | |||
| 691b9458ec | |||
| b095acd4a5 | |||
| afbb8225d8 | |||
| 35678b06a8 | |||
| 96d39ecb30 | |||
| 2c7b11a691 | |||
| 83c288d739 | |||
| 8c6b853ee5 | |||
| b414d7d026 | |||
| ae6ec809b8 | |||
| f47214ae0a | |||
| bddd1b0984 | |||
| e2e77385b1 | |||
| f4c13032a2 | |||
| 43801d0824 | |||
| 16cd027bf3 | |||
| f361c4bbdb | |||
| c4f5777536 | |||
| c740d27b0e | |||
| 800b163de9 | |||
| 7f317d0fb6 | |||
| 714cdd84ad | |||
| 26b5172aea | |||
| 47b95f5650 | |||
| 989a5441f3 | |||
| 6394a7aae0 | |||
| beff9d5241 | |||
|
|
83c3201ef8 | ||
|
|
dcba97f84a | ||
|
|
ca6544204b | ||
|
|
1c3d1b623d | ||
|
|
bf21b0a267 | ||
|
|
afc4158dd3 | ||
|
|
09ead0cc7a | ||
|
|
f2e840577a | ||
|
|
345cbdb8d4 | ||
|
|
0ebda18669 | ||
|
|
efa081716f | ||
|
|
7225737984 | ||
|
|
0b1a64305a | ||
|
|
bfd972b96d | ||
|
|
25f26a7a91 | ||
|
|
d9ae41ed10 | ||
|
|
68877eebe3 | ||
|
|
5ed18c7448 | ||
|
|
1fda1d749d | ||
|
|
ac728f1a31 | ||
|
|
8beeea0da1 | ||
|
|
fc4b79239b | ||
|
|
618027b181 | ||
|
|
f97ead8a20 | ||
|
|
bae381430a | ||
|
|
1c3f7fcec0 | ||
|
|
65a219512c | ||
|
|
bb12562c2f | ||
|
|
b81b0b7616 | ||
|
|
bd9a5f03a4 | ||
|
|
9d5d80bf4a | ||
|
|
44e894f406 | ||
|
|
366b47ad80 | ||
|
|
b3508b9fe1 | ||
|
|
3f2eab5206 | ||
|
|
5bdf5da142 | ||
| c823257b79 | |||
|
|
937d369856 | ||
|
|
060bc0aaf8 | ||
|
|
c81ddd09cc | ||
|
|
015c4ab475 | ||
|
|
ccdf004404 | ||
|
|
9049093267 | ||
|
|
9d4d9ccf38 | ||
|
|
8b1d678f2e | ||
|
|
67db774a2f | ||
|
|
3cd951f0a0 | ||
|
|
0525ce2cb3 | ||
|
|
5e74ec01ce | ||
|
|
bbbc0c9d50 | ||
|
|
25067959eb | ||
|
|
086ddc96bb | ||
|
|
3394de0b93 | ||
| 16be2fc857 | |||
|
|
abd0c7dece | ||
|
|
ee540b3cb7 | ||
|
|
c146e156ec | ||
|
|
6efb015169 | ||
|
|
a982e0a111 | ||
|
|
84843f8cbb | ||
|
|
dccb43702e | ||
|
|
f459249f78 | ||
|
|
3ad369501a | ||
|
|
b0fe4373b0 | ||
|
|
9df5ed5b7f | ||
|
|
aa8add7b38 | ||
|
|
21f8dab5de | ||
|
|
4baa38c0cc | ||
|
|
3c091dc214 | ||
|
|
58090aa6d6 | ||
|
|
2521ed4ad5 | ||
|
|
6a5f22400d | ||
|
|
a5fffc0c9e | ||
|
|
e551ecbe5f | ||
| 561239a4b2 | |||
| 389b2e6148 | |||
| 9403b87788 | |||
| 64cceac913 | |||
| c523079f0e | |||
|
|
8542f78b0b | ||
|
|
da513972e8 | ||
|
|
be293a957a | ||
|
|
8e26591c0b | ||
|
|
4e31d436d5 | ||
|
|
b6f7914b14 | ||
|
|
9ffbe1f8ca | ||
|
|
4e0cd9e8a9 | ||
|
|
24f3dfe264 | ||
|
|
42fc62eb68 | ||
|
|
b1392be3a1 | ||
|
|
04dde7a3f2 | ||
|
|
44fae3838e | ||
|
|
f11306af24 | ||
|
|
4057dc189d | ||
|
|
fc98b5f1f0 | ||
|
|
4d6282a5b4 | ||
|
|
0e058b2590 | ||
|
|
a31279954a | ||
|
|
d25cb7a9da | ||
| 942124fdc3 | |||
| 9085874d4e | |||
| 2f5562f8eb | |||
| 6733e45729 | |||
| 37438afbf6 | |||
| 7c34b1c855 | |||
| 3dc2e55627 | |||
| c658dd72e7 | |||
| 5b8c81dfac | |||
| bf4ec5f91a | |||
| 15024b38b9 | |||
| 71ec415cc4 | |||
| 81b6f47d8a | |||
| e55fd18771 | |||
| fd97c2bdf2 | |||
| 6ca71a872d | |||
| 18e92425bb | |||
| 3feebe8910 | |||
| 9fc7fc7a2e | |||
| 642d90a293 | |||
| f5313b9ffd | |||
|
|
7abed39473 | ||
| ffc40ba634 | |||
| 84f3cda190 | |||
| 0f20f387fc | |||
| 67093a0d28 | |||
| 63eaf1adf2 | |||
| 28d167b4f8 | |||
| 7bff09eeb9 | |||
| 5afde966ef | |||
| 5df1f32305 | |||
| 670f2ee2b0 | |||
| 5abf336696 | |||
| 7ae0a65c0e | |||
| 9e88233957 | |||
| d0a4213538 | |||
| b2467edc0f | |||
| 94e398a6b3 | |||
| e5ca67618f | |||
| 2da908d9b8 | |||
| 34f187161c | |||
| 0e5e0169bf | |||
| f318d3aadc | |||
| 43e38df8b0 | |||
| 86b999f6a4 | |||
| 553ca7d71c | |||
| 2594cc4546 | |||
| 2cd03eceaa | |||
| d8feec325a | |||
| 71b7f110e6 | |||
|
|
1b04c9a7b1 | ||
|
|
6a27e5338a | ||
|
|
5ad323c7cb | ||
|
|
9c065d55e0 | ||
| 10a906d51b | |||
| f61779119b | |||
|
|
0991628a78 | ||
|
|
703e83cd48 | ||
|
|
a50c21cf36 | ||
|
|
ecb80e0f34 | ||
|
|
aded4bfdeb | ||
|
|
22764f5362 | ||
|
|
1b84f57a5b | ||
|
|
23f4a82bbc | ||
|
|
9fbfc83535 | ||
|
|
ad8d84bfd7 | ||
|
|
4257f1e2ac | ||
|
|
8166970038 | ||
|
|
88530606df | ||
|
|
d9b3443818 |
6
.github/workflows/cd.yml
vendored
6
.github/workflows/cd.yml
vendored
@@ -1,13 +1,13 @@
|
|||||||
name: Continuous Deployment
|
name: Continuous Deployment
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '15 4 * * *'
|
- cron: '15 6 * * *'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DOTNET_NOLOGO: true
|
DOTNET_NOLOGO: true
|
||||||
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||||
GIT_LFS_PULL_OPTIONS: '-c lfs.concurrenttransfers=10 -c lfs.transfer.maxretries=2'
|
GIT_LFS_PULL_OPTIONS: '-c lfs.concurrenttransfers=1 -c lfs.transfer.maxretries=2 -c http.version="HTTP/1.1" -c lfs.activitytimeout=60'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ jobs:
|
|||||||
- name: Checkout LFS
|
- name: Checkout LFS
|
||||||
run: |
|
run: |
|
||||||
git lfs version
|
git lfs version
|
||||||
GIT_TRACE=1 GIT_TRANSFER_TRACE=1 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 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 libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Redirect to our own Git LFS server
|
# Redirect to our own Git LFS server
|
||||||
[lfs]
|
[lfs]
|
||||||
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||||
locksverify = false
|
locksverify = false
|
||||||
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
BIN
Content/Editor/Camera/M_Camera.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/CubeTexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/DDGIDebugProbes.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Decal.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Particle.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Surface.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/SurfaceAdditive.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
BIN
Content/Editor/DebugMaterials/SingleColor/Terrain.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/DefaultFontMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/FoliageBrushMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/MaterialWire.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/SelectionOutlineMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Gizmo/VertexColorsPreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Highlight Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/Icons/IconsMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/IesProfilePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Particle Material Color.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Particles/Smoke Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/SpriteMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Circle Brush Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Terrain/Highlight Terrain Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
BIN
Content/Editor/TexturePreviewMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
BIN
Content/Editor/Wires Debug Material.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultDeformableMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultRadialMenu.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultRadialMenu.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/DefaultTerrainMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SingleColorMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
BIN
Content/Engine/SkyboxMaterial.flax
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Shaders/Editor/Grid.flax
(Stored with Git LFS)
BIN
Content/Shaders/Editor/Grid.flax
(Stored with Git LFS)
Binary file not shown.
@@ -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!
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
|||||||
# Build bindings for all editor configurations
|
# Build bindings for all editor configurations
|
||||||
echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
# TODO: Detect the correct architecture here
|
# 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
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Linux/CallBuildTool.sh --genproject "$@"
|
|||||||
# Build bindings for all editor configurations
|
# Build bindings for all editor configurations
|
||||||
echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
# TODO: Detect the correct architecture here
|
# 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
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using FlaxEditor.Content.Create;
|
using FlaxEditor.Content.Create;
|
||||||
using FlaxEditor.CustomEditors;
|
using FlaxEditor.CustomEditors;
|
||||||
using FlaxEditor.CustomEditors.Editors;
|
using FlaxEditor.CustomEditors.Editors;
|
||||||
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Windows;
|
using FlaxEditor.Windows;
|
||||||
using FlaxEditor.Windows.Assets;
|
using FlaxEditor.Windows.Assets;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
@@ -84,18 +86,67 @@ namespace FlaxEditor.Content
|
|||||||
|
|
||||||
if (_element != null)
|
if (_element != null)
|
||||||
{
|
{
|
||||||
// Define the rule for the types that can be used to create a json data asset
|
_element.CustomControl.CheckValid += OnCheckValidJsonAssetType;
|
||||||
_element.CustomControl.CheckValid += type =>
|
|
||||||
type.Type != null &&
|
|
||||||
type.IsClass &&
|
|
||||||
type.Type.IsVisible &&
|
|
||||||
!type.IsAbstract &&
|
|
||||||
!type.IsGenericType &&
|
|
||||||
type.Type.GetConstructor(Type.EmptyTypes) != null &&
|
|
||||||
!typeof(FlaxEngine.GUI.Control).IsAssignableFrom(type.Type) &&
|
|
||||||
!typeof(FlaxEngine.Object).IsAssignableFrom(type.Type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Type[] BlacklistedClasses =
|
||||||
|
[
|
||||||
|
typeof(System.Attribute),
|
||||||
|
typeof(FlaxEngine.Object),
|
||||||
|
typeof(FlaxEngine.GUI.Control),
|
||||||
|
];
|
||||||
|
|
||||||
|
private static Type[] BlacklistedStructs =
|
||||||
|
[
|
||||||
|
typeof(Float2),
|
||||||
|
typeof(Float3),
|
||||||
|
typeof(Float4),
|
||||||
|
typeof(Double2),
|
||||||
|
typeof(Double3),
|
||||||
|
typeof(Double4),
|
||||||
|
typeof(Vector2),
|
||||||
|
typeof(Vector3),
|
||||||
|
typeof(Vector4),
|
||||||
|
typeof(Half2),
|
||||||
|
typeof(Half3),
|
||||||
|
typeof(Half4),
|
||||||
|
typeof(Int2),
|
||||||
|
typeof(Int3),
|
||||||
|
typeof(Int4),
|
||||||
|
typeof(Transform),
|
||||||
|
typeof(Quaternion),
|
||||||
|
typeof(BoundingBox),
|
||||||
|
typeof(BoundingSphere),
|
||||||
|
typeof(BoundingFrustum),
|
||||||
|
typeof(Ray),
|
||||||
|
typeof(Plane),
|
||||||
|
typeof(Matrix),
|
||||||
|
typeof(Color),
|
||||||
|
typeof(Color32),
|
||||||
|
typeof(FloatR11G11B10),
|
||||||
|
typeof(FloatR10G10B10A2),
|
||||||
|
typeof(FlaxEngine.Half),
|
||||||
|
];
|
||||||
|
|
||||||
|
private static bool OnCheckValidJsonAssetType(ScriptType type)
|
||||||
|
{
|
||||||
|
// Define the rule for the types that can be used to create a json data asset
|
||||||
|
var mType = type.Type;
|
||||||
|
if (mType == null ||
|
||||||
|
type.IsAbstract ||
|
||||||
|
type.IsStatic ||
|
||||||
|
type.IsGenericType ||
|
||||||
|
!mType.IsVisible)
|
||||||
|
return false;
|
||||||
|
if (type.IsClass)
|
||||||
|
return mType.GetConstructor(Type.EmptyTypes) != null && BlacklistedClasses.FirstOrDefault(x => x.IsAssignableFrom(mType)) == null;
|
||||||
|
if (type.IsStructure)
|
||||||
|
return !type.IsPrimitive &&
|
||||||
|
!type.IsVoid &&
|
||||||
|
!BlacklistedStructs.Contains(mType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +226,7 @@ namespace FlaxEditor.Content
|
|||||||
{
|
{
|
||||||
_thumbnail = SpriteHandle.Invalid;
|
_thumbnail = SpriteHandle.Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor with overriden thumbnail.
|
/// Constructor with overriden thumbnail.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -196,7 +247,7 @@ namespace FlaxEditor.Content
|
|||||||
{
|
{
|
||||||
Editor.SaveJsonAsset(outputPath, new T());
|
Editor.SaveJsonAsset(outputPath, new T());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
|
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -496,7 +496,7 @@ namespace FlaxEditor.Content.Thumbnails
|
|||||||
// Prepare requests
|
// Prepare requests
|
||||||
bool isAnyReady = false;
|
bool isAnyReady = false;
|
||||||
int checks = Mathf.Min(10, _requests.Count);
|
int checks = Mathf.Min(10, _requests.Count);
|
||||||
for (int i = 0; i < checks; i++)
|
for (int i = 0; i < checks && i < _requests.Count; i++)
|
||||||
{
|
{
|
||||||
var request = _requests[i];
|
var request = _requests[i];
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -1277,6 +1277,8 @@ bool CookAssetsStep::Perform(CookingData& data)
|
|||||||
assetStats.Count++;
|
assetStats.Count++;
|
||||||
assetStats.ContentSize += FileSystem::GetFileSize(cookedFilePath);
|
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))
|
if (packageBuilder.Add(data, i->Value, cookedFilePath))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -415,9 +415,9 @@ bool DeployDataStep::Perform(CookingData& data)
|
|||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/NormalTexture"));
|
data.AddRootEngineAsset(TEXT("Engine/Textures/NormalTexture"));
|
||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/BlackTexture"));
|
data.AddRootEngineAsset(TEXT("Engine/Textures/BlackTexture"));
|
||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/WhiteTexture"));
|
data.AddRootEngineAsset(TEXT("Engine/Textures/WhiteTexture"));
|
||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensStarburst"));
|
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensStarburst"));
|
||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensColor"));
|
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensColor"));
|
||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensDirt"));
|
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensDirt"));
|
||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Circle"));
|
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Circle"));
|
||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Hexagon"));
|
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Hexagon"));
|
||||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Octagon"));
|
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Octagon"));
|
||||||
|
|||||||
@@ -195,6 +195,15 @@ namespace FlaxEditor.CustomEditors
|
|||||||
Presenter.AfterLayout?.Invoke(layout);
|
Presenter.AfterLayout?.Invoke(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Deinitialize()
|
||||||
|
{
|
||||||
|
Editor = null;
|
||||||
|
_overrideEditor = null;
|
||||||
|
|
||||||
|
base.Deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void OnModified()
|
protected override void OnModified()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,12 +68,16 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
// Use default prefab instance as a reference for the editor
|
// Use default prefab instance as a reference for the editor
|
||||||
Values.SetReferenceValue(prefabInstance);
|
Values.SetReferenceValue(prefabInstance);
|
||||||
|
|
||||||
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
|
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
|
||||||
|
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;
|
||||||
|
panel.CustomControl.SlotsVertically = 1;
|
||||||
|
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter || nestedPrefab)
|
||||||
{
|
{
|
||||||
// Add some UI
|
var targetPrefab = nestedPrefab ?? prefab;
|
||||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
|
||||||
panel.CustomControl.Height = 20.0f;
|
|
||||||
panel.CustomControl.SlotsVertically = 1;
|
|
||||||
panel.CustomControl.SlotsHorizontally = 3;
|
panel.CustomControl.SlotsHorizontally = 3;
|
||||||
|
|
||||||
// Selecting actor prefab asset
|
// Selecting actor prefab asset
|
||||||
@@ -81,17 +85,21 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
selectPrefab.Button.Clicked += () =>
|
selectPrefab.Button.Clicked += () =>
|
||||||
{
|
{
|
||||||
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
|
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
|
||||||
Editor.Instance.Windows.ContentWin.Select(prefab);
|
Editor.Instance.Windows.ContentWin.Select(targetPrefab);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Edit selected prefab asset
|
// Edit selected prefab asset
|
||||||
var editPrefab = panel.Button("Edit Prefab");
|
var editPrefab = panel.Button("Edit Prefab");
|
||||||
editPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(prefab.ID));
|
editPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(targetPrefab.ID));
|
||||||
|
|
||||||
// Viewing changes applied to this actor
|
|
||||||
var viewChanges = panel.Button("View Changes");
|
|
||||||
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
panel.CustomControl.SlotsHorizontally = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Viewing changes applied to this actor
|
||||||
|
var viewChanges = panel.Button("View Changes");
|
||||||
|
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
||||||
|
|
||||||
// Link event to update editor on prefab apply
|
// Link event to update editor on prefab apply
|
||||||
_linkedPrefabId = prefab.ID;
|
_linkedPrefabId = prefab.ID;
|
||||||
@@ -198,7 +206,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
if (_linkedPrefabId != Guid.Empty)
|
if (_linkedPrefabId != Guid.Empty)
|
||||||
{
|
{
|
||||||
_linkedPrefabId = Guid.Empty;
|
_linkedPrefabId = Guid.Empty;
|
||||||
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplying;
|
Editor.Instance.Prefabs.PrefabApplying -= OnPrefabApplying;
|
||||||
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplied;
|
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplied;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,13 +15,23 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
private int _firstTimeShow;
|
private int _firstTimeShow;
|
||||||
private BezierCurveEditor<T> _curve;
|
private BezierCurveEditor<T> _curve;
|
||||||
private Splitter _splitter;
|
private Splitter _splitter;
|
||||||
|
private string _heightCachedPath;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
var item = layout.CustomContainer<BezierCurveEditor<T>>();
|
var item = layout.CustomContainer<BezierCurveEditor<T>>();
|
||||||
_curve = item.CustomControl;
|
_curve = item.CustomControl;
|
||||||
_curve.Height = 120.0f;
|
var height = 120.0f;
|
||||||
|
var presenter = Presenter;
|
||||||
|
if (presenter != null && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
||||||
|
{
|
||||||
|
// Try to restore curve height
|
||||||
|
_heightCachedPath = layout.GetLayoutCachePath("Height");
|
||||||
|
if (Editor.Instance.ProjectCache.TryGetCustomData(_heightCachedPath, out float cachedHeight) && cachedHeight > 10.0f)
|
||||||
|
height = cachedHeight;
|
||||||
|
}
|
||||||
|
_curve.Height = height;
|
||||||
_curve.Edited += OnCurveEdited;
|
_curve.Edited += OnCurveEdited;
|
||||||
_firstTimeShow = 4; // For some weird reason it needs several frames of warmup (probably due to sliders smoothing)
|
_firstTimeShow = 4; // For some weird reason it needs several frames of warmup (probably due to sliders smoothing)
|
||||||
_splitter = new Splitter
|
_splitter = new Splitter
|
||||||
@@ -45,7 +55,11 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
|
|
||||||
private void OnSplitterMoved(Float2 location)
|
private void OnSplitterMoved(Float2 location)
|
||||||
{
|
{
|
||||||
_curve.Height = Mathf.Clamp(_splitter.PointToParent(location).Y, 50.0f, 1000.0f);
|
_curve.Height = Mathf.Clamp(_splitter.PointToParent(location).Y, 50.0f, 1000.0f);
|
||||||
|
|
||||||
|
// Cache curve height
|
||||||
|
if (_heightCachedPath != null)
|
||||||
|
Editor.Instance.ProjectCache.SetCustomData(_heightCachedPath, _curve.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -133,13 +147,23 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
private int _firstTimeShow;
|
private int _firstTimeShow;
|
||||||
private LinearCurveEditor<T> _curve;
|
private LinearCurveEditor<T> _curve;
|
||||||
private Splitter _splitter;
|
private Splitter _splitter;
|
||||||
|
private string _heightCachedPath;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
var item = layout.CustomContainer<LinearCurveEditor<T>>();
|
var item = layout.CustomContainer<LinearCurveEditor<T>>();
|
||||||
_curve = item.CustomControl;
|
_curve = item.CustomControl;
|
||||||
_curve.Height = 120.0f;
|
var height = 120.0f;
|
||||||
|
var presenter = Presenter;
|
||||||
|
if (presenter != null && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
||||||
|
{
|
||||||
|
// Try to restore curve height
|
||||||
|
_heightCachedPath = layout.GetLayoutCachePath("Height");
|
||||||
|
if (Editor.Instance.ProjectCache.TryGetCustomData(_heightCachedPath, out float cachedHeight) && cachedHeight > 10.0f)
|
||||||
|
height = cachedHeight;
|
||||||
|
}
|
||||||
|
_curve.Height = height;
|
||||||
_curve.Edited += OnCurveEdited;
|
_curve.Edited += OnCurveEdited;
|
||||||
_firstTimeShow = 4; // For some weird reason it needs several frames of warmup (probably due to sliders smoothing)
|
_firstTimeShow = 4; // For some weird reason it needs several frames of warmup (probably due to sliders smoothing)
|
||||||
_splitter = new Splitter
|
_splitter = new Splitter
|
||||||
@@ -164,6 +188,10 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
private void OnSplitterMoved(Float2 location)
|
private void OnSplitterMoved(Float2 location)
|
||||||
{
|
{
|
||||||
_curve.Height = Mathf.Clamp(_splitter.PointToParent(location).Y, 50.0f, 1000.0f);
|
_curve.Height = Mathf.Clamp(_splitter.PointToParent(location).Y, 50.0f, 1000.0f);
|
||||||
|
|
||||||
|
// Cache curve height
|
||||||
|
if (_heightCachedPath != null)
|
||||||
|
Editor.Instance.ProjectCache.SetCustomData(_heightCachedPath, _curve.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -1057,6 +1057,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
|||||||
protected override void Deinitialize()
|
protected override void Deinitialize()
|
||||||
{
|
{
|
||||||
_scriptToggles = null;
|
_scriptToggles = null;
|
||||||
|
_scripts.Clear();
|
||||||
|
|
||||||
base.Deinitialize();
|
base.Deinitialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
base.Refresh();
|
base.Refresh();
|
||||||
|
|
||||||
if (!HasDifferentValues)
|
var differentValues = HasDifferentValues;
|
||||||
|
Picker.DifferentValues = differentValues;
|
||||||
|
if (!differentValues)
|
||||||
{
|
{
|
||||||
_isRefreshing = true;
|
_isRefreshing = true;
|
||||||
var value = Values[0];
|
var value = Values[0];
|
||||||
@@ -375,12 +377,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
base.Refresh();
|
base.Refresh();
|
||||||
|
|
||||||
if (!HasDifferentValues)
|
_isRefreshing = true;
|
||||||
{
|
_textBox.Text = HasDifferentValues ? "Multiple Values" : GetPath();
|
||||||
_isRefreshing = true;
|
_isRefreshing = false;
|
||||||
_textBox.Text = GetPath();
|
|
||||||
_isRefreshing = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
_label = layout.ClickableLabel(Path).CustomControl;
|
_label = layout.ClickableLabel(Path).CustomControl;
|
||||||
|
_label.Margin = new Margin(0, 20.0f, 0, 0);
|
||||||
|
_label.ClipText = true;
|
||||||
_label.RightClick += ShowPicker;
|
_label.RightClick += ShowPicker;
|
||||||
var button = new Button
|
var button = new Button
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ using FlaxEditor.GUI.Drag;
|
|||||||
using FlaxEditor.SceneGraph;
|
using FlaxEditor.SceneGraph;
|
||||||
using FlaxEditor.SceneGraph.GUI;
|
using FlaxEditor.SceneGraph.GUI;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
|
using FlaxEditor.Windows;
|
||||||
|
using FlaxEditor.Windows.Assets;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
@@ -40,6 +42,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
private DragScripts _dragScripts;
|
private DragScripts _dragScripts;
|
||||||
private DragHandlers _dragHandlers;
|
private DragHandlers _dragHandlers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The presenter using this control.
|
||||||
|
/// </summary>
|
||||||
|
public IPresenterOwner PresenterContext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the allowed objects type (given type and all sub classes). 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>
|
/// </summary>
|
||||||
@@ -129,6 +136,11 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<Object, ScriptType, bool> CheckValid;
|
public Func<Object, ScriptType, bool> CheckValid;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Utility flag used to indicate that there are different values assigned to this reference editor and user should be informed about it.
|
||||||
|
/// </summary>
|
||||||
|
public bool DifferentValues;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="FlaxObjectRefPickerControl"/> class.
|
/// Initializes a new instance of the <see cref="FlaxObjectRefPickerControl"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -154,7 +166,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
Value = actor;
|
Value = actor;
|
||||||
RootWindow.Focus();
|
RootWindow.Focus();
|
||||||
Focus();
|
Focus();
|
||||||
});
|
}, PresenterContext);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -163,7 +175,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
Value = script;
|
Value = script;
|
||||||
RootWindow.Focus();
|
RootWindow.Focus();
|
||||||
Focus();
|
Focus();
|
||||||
});
|
}, PresenterContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +209,14 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
Render2D.DrawRectangle(frameRect, isEnabled && (IsMouseOver || IsNavFocused) ? style.BorderHighlighted : style.BorderNormal);
|
Render2D.DrawRectangle(frameRect, isEnabled && (IsMouseOver || IsNavFocused) ? style.BorderHighlighted : style.BorderNormal);
|
||||||
|
|
||||||
// Check if has item selected
|
// Check if has item selected
|
||||||
if (isSelected)
|
if (DifferentValues)
|
||||||
|
{
|
||||||
|
// Draw info
|
||||||
|
Render2D.PushClip(nameRect);
|
||||||
|
Render2D.DrawText(style.FontMedium, Type != null ? $"Multiple Values ({Utilities.Utils.GetPropertyNameUI(Type.ToString())})" : "-", nameRect, isEnabled ? style.ForegroundGrey : style.ForegroundGrey.AlphaMultiplied(0.75f), TextAlignment.Near, TextAlignment.Center);
|
||||||
|
Render2D.PopClip();
|
||||||
|
}
|
||||||
|
else if (isSelected)
|
||||||
{
|
{
|
||||||
// Draw name
|
// Draw name
|
||||||
Render2D.PushClip(nameRect);
|
Render2D.PushClip(nameRect);
|
||||||
@@ -326,10 +345,19 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_linkedTreeNode = Editor.Instance.Scene.GetActorNode(actor).TreeNode;
|
if (PresenterContext is PropertiesWindow)
|
||||||
_linkedTreeNode.ExpandAllParents();
|
_linkedTreeNode = Editor.Instance.Scene.GetActorNode(actor).TreeNode;
|
||||||
Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true);
|
else if (PresenterContext is PrefabWindow prefabWindow)
|
||||||
_linkedTreeNode.StartHighlight();
|
_linkedTreeNode = prefabWindow.Graph.Root.Find(actor).TreeNode;
|
||||||
|
if (_linkedTreeNode != null)
|
||||||
|
{
|
||||||
|
_linkedTreeNode.ExpandAllParents();
|
||||||
|
if (PresenterContext is PropertiesWindow)
|
||||||
|
Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true);
|
||||||
|
else if (PresenterContext is PrefabWindow prefabWindow)
|
||||||
|
(prefabWindow.Tree.Parent as Panel).ScrollViewTo(_linkedTreeNode, true);
|
||||||
|
_linkedTreeNode.StartHighlight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -372,9 +400,20 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
// Select object
|
// Select object
|
||||||
if (_value is Actor actor)
|
if (_value is Actor actor)
|
||||||
Editor.Instance.SceneEditing.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)
|
else if (_value is Script script && script.Actor)
|
||||||
Editor.Instance.SceneEditing.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)
|
else if (_value is Asset asset)
|
||||||
Editor.Instance.Windows.ContentWin.Select(asset);
|
Editor.Instance.Windows.ContentWin.Select(asset);
|
||||||
}
|
}
|
||||||
@@ -415,13 +454,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
// Ensure to have valid drag helpers (uses lazy init)
|
// Ensure to have valid drag helpers (uses lazy init)
|
||||||
if (_dragActors == null)
|
if (_dragActors == null)
|
||||||
_dragActors = new DragActors(x => IsValid(x.Actor));
|
_dragActors = new DragActors(ValidateDragActor);
|
||||||
if (_dragActorsWithScript == null)
|
if (_dragActorsWithScript == null)
|
||||||
_dragActorsWithScript = new DragActors(ValidateDragActorWithScript);
|
_dragActorsWithScript = new DragActors(ValidateDragActorWithScript);
|
||||||
if (_dragAssets == null)
|
if (_dragAssets == null)
|
||||||
_dragAssets = new DragAssets(ValidateDragAsset);
|
_dragAssets = new DragAssets(ValidateDragAsset);
|
||||||
if (_dragScripts == null)
|
if (_dragScripts == null)
|
||||||
_dragScripts = new DragScripts(IsValid);
|
_dragScripts = new DragScripts(ValidateDragScript);
|
||||||
if (_dragHandlers == null)
|
if (_dragHandlers == null)
|
||||||
{
|
{
|
||||||
_dragHandlers = new DragHandlers
|
_dragHandlers = new DragHandlers
|
||||||
@@ -446,6 +485,43 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
return DragEffect;
|
return DragEffect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ValidateDragActor(ActorNode a)
|
||||||
|
{
|
||||||
|
if (!IsValid(a.Actor))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (PresenterContext is PrefabWindow prefabWindow)
|
||||||
|
{
|
||||||
|
if (prefabWindow.Tree == a.TreeNode.ParentTree)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (PresenterContext is PropertiesWindow || PresenterContext == null)
|
||||||
|
{
|
||||||
|
if (a.ParentScene != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ValidateDragScript(Script script)
|
||||||
|
{
|
||||||
|
if (!IsValid(script))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (PresenterContext is PrefabWindow prefabWindow)
|
||||||
|
{
|
||||||
|
var actorNode = prefabWindow.Graph.Root.Find(script.Actor);
|
||||||
|
if (actorNode != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (PresenterContext is PropertiesWindow || PresenterContext == null)
|
||||||
|
{
|
||||||
|
if (script.Actor.HasScene)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private bool ValidateDragAsset(AssetItem assetItem)
|
private bool ValidateDragAsset(AssetItem assetItem)
|
||||||
{
|
{
|
||||||
// Check if can accept assets
|
// Check if can accept assets
|
||||||
@@ -464,7 +540,18 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
private bool ValidateDragActorWithScript(ActorNode node)
|
private bool ValidateDragActorWithScript(ActorNode node)
|
||||||
{
|
{
|
||||||
return node.Actor.Scripts.Any(IsValid);
|
bool isCorrectContext = false;
|
||||||
|
if (PresenterContext is PrefabWindow prefabWindow)
|
||||||
|
{
|
||||||
|
if (prefabWindow.Tree == node.TreeNode.ParentTree)
|
||||||
|
isCorrectContext = true;
|
||||||
|
}
|
||||||
|
else if (PresenterContext is PropertiesWindow || PresenterContext == null)
|
||||||
|
{
|
||||||
|
if (node.ParentScene != null)
|
||||||
|
isCorrectContext = true;
|
||||||
|
}
|
||||||
|
return node.Actor.Scripts.Any(IsValid) && isCorrectContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -536,6 +623,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
if (!HasDifferentTypes)
|
if (!HasDifferentTypes)
|
||||||
{
|
{
|
||||||
_element = layout.Custom<FlaxObjectRefPickerControl>();
|
_element = layout.Custom<FlaxObjectRefPickerControl>();
|
||||||
|
_element.CustomControl.PresenterContext = Presenter.Owner;
|
||||||
_element.CustomControl.Type = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
|
_element.CustomControl.Type = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
|
||||||
_element.CustomControl.ValueChanged += () => SetValue(_element.CustomControl.Value);
|
_element.CustomControl.ValueChanged += () => SetValue(_element.CustomControl.Value);
|
||||||
}
|
}
|
||||||
@@ -546,7 +634,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
base.Refresh();
|
base.Refresh();
|
||||||
|
|
||||||
if (!HasDifferentValues)
|
var differentValues = HasDifferentValues;
|
||||||
|
_element.CustomControl.DifferentValues = differentValues;
|
||||||
|
if (!differentValues)
|
||||||
{
|
{
|
||||||
_element.CustomControl.Value = Values[0] as Object;
|
_element.CustomControl.Value = Values[0] as Object;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -819,6 +819,15 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
OnGroupsEnd();
|
OnGroupsEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Deinitialize()
|
||||||
|
{
|
||||||
|
_visibleIfCaches = null;
|
||||||
|
_visibleIfPropertiesListsCache = null;
|
||||||
|
|
||||||
|
base.Deinitialize();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Refresh()
|
public override void Refresh()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,6 +96,20 @@ namespace FlaxEditor.CustomEditors
|
|||||||
menu.Show(groupPanel, location);
|
menu.Show(groupPanel, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal string GetLayoutCachePath(string name)
|
||||||
|
{
|
||||||
|
// Build group identifier (made of path from group titles)
|
||||||
|
var expandPath = name;
|
||||||
|
var container = this;
|
||||||
|
while (container != null && !(container is CustomEditorPresenter))
|
||||||
|
{
|
||||||
|
if (container.ContainerControl is DropPanel dropPanel)
|
||||||
|
expandPath = dropPanel.HeaderText + "/" + expandPath;
|
||||||
|
container = container._parent;
|
||||||
|
}
|
||||||
|
return expandPath;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds new group element.
|
/// Adds new group element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -112,14 +126,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
if (presenter != null && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
if (presenter != null && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
||||||
{
|
{
|
||||||
// Build group identifier (made of path from group titles)
|
// Build group identifier (made of path from group titles)
|
||||||
var expandPath = title;
|
var expandPath = GetLayoutCachePath(title);
|
||||||
var container = this;
|
|
||||||
while (container != null && !(container is CustomEditorPresenter))
|
|
||||||
{
|
|
||||||
if (container.ContainerControl is DropPanel dropPanel)
|
|
||||||
expandPath = dropPanel.HeaderText + "/" + expandPath;
|
|
||||||
container = container._parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Caching/restoring expanded groups (non-root groups cache expanded state so invert boolean expression)
|
// Caching/restoring expanded groups (non-root groups cache expanded state so invert boolean expression)
|
||||||
if (Editor.Instance.ProjectCache.IsGroupToggled(expandPath) ^ isSubGroup)
|
if (Editor.Instance.ProjectCache.IsGroupToggled(expandPath) ^ isSubGroup)
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ namespace FlaxEditor.CustomEditors
|
|||||||
if (objA == null && objB is string objBStr && objBStr.Length == 0)
|
if (objA == null && objB is string objBStr && objBStr.Length == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return Newtonsoft.Json.Utilities.MiscellaneousUtils.ValueEquals(objA, objB);
|
return FlaxEngine.Json.JsonSerializer.ValueEquals(objA, objB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1686,9 +1686,6 @@ namespace FlaxEditor
|
|||||||
[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_GetPrefabNestedObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
|
||||||
internal static partial void Internal_GetPrefabNestedObject(IntPtr prefabId, IntPtr prefabObjectId, IntPtr outPrefabId, IntPtr outPrefabObjectId);
|
|
||||||
|
|
||||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||||
internal static partial float Internal_GetAnimationTime(IntPtr animatedModel);
|
internal static partial float Internal_GetAnimationTime(IntPtr animatedModel);
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,11 @@ namespace FlaxEditor.GUI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CanEdit = true;
|
public bool CanEdit = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Utility flag used to indicate that there are different values assigned to this reference editor and user should be informed about it.
|
||||||
|
/// </summary>
|
||||||
|
public bool DifferentValues;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="AssetPicker"/> class.
|
/// Initializes a new instance of the <see cref="AssetPicker"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -121,7 +126,13 @@ namespace FlaxEditor.GUI
|
|||||||
if (CanEdit)
|
if (CanEdit)
|
||||||
Render2D.DrawSprite(style.ArrowDown, button1Rect, button1Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
Render2D.DrawSprite(style.ArrowDown, button1Rect, button1Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
||||||
|
|
||||||
if (Validator.SelectedItem != null)
|
if (DifferentValues)
|
||||||
|
{
|
||||||
|
// No element selected
|
||||||
|
Render2D.FillRectangle(iconRect, style.BackgroundNormal);
|
||||||
|
Render2D.DrawText(style.FontMedium, "Multiple\nValues", iconRect, style.Foreground, TextAlignment.Center, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, Height / DefaultIconSize);
|
||||||
|
}
|
||||||
|
else if (Validator.SelectedItem != null)
|
||||||
{
|
{
|
||||||
// Draw item preview
|
// Draw item preview
|
||||||
Validator.SelectedItem.DrawThumbnail(ref iconRect);
|
Validator.SelectedItem.DrawThumbnail(ref iconRect);
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ namespace FlaxEditor.GUI
|
|||||||
internal bool _isMovingTangent;
|
internal bool _isMovingTangent;
|
||||||
internal bool _movedView;
|
internal bool _movedView;
|
||||||
internal bool _movedKeyframes;
|
internal bool _movedKeyframes;
|
||||||
|
internal bool _toggledSelection;
|
||||||
private TangentPoint _movingTangent;
|
private TangentPoint _movingTangent;
|
||||||
private Float2 _movingSelectionStart;
|
private Float2 _movingSelectionStart;
|
||||||
|
private Float2 _movingSelectionStartPosLock;
|
||||||
private Float2[] _movingSelectionOffsets;
|
private Float2[] _movingSelectionOffsets;
|
||||||
private Float2 _cmShowPos;
|
private Float2 _cmShowPos;
|
||||||
|
|
||||||
@@ -56,12 +58,11 @@ namespace FlaxEditor.GUI
|
|||||||
internal void UpdateSelection(ref Rectangle selectionRect)
|
internal void UpdateSelection(ref Rectangle selectionRect)
|
||||||
{
|
{
|
||||||
// Find controls to select
|
// Find controls to select
|
||||||
for (int i = 0; i < Children.Count; i++)
|
var children = _children;
|
||||||
|
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(ref selectionRect);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_editor.UpdateTangents();
|
_editor.UpdateTangents();
|
||||||
}
|
}
|
||||||
@@ -72,6 +73,7 @@ namespace FlaxEditor.GUI
|
|||||||
_isMovingSelection = true;
|
_isMovingSelection = true;
|
||||||
_movedKeyframes = false;
|
_movedKeyframes = false;
|
||||||
var viewRect = _editor._mainPanel.GetClientArea();
|
var viewRect = _editor._mainPanel.GetClientArea();
|
||||||
|
_movingSelectionStartPosLock = location;
|
||||||
_movingSelectionStart = PointToKeyframes(location, ref viewRect);
|
_movingSelectionStart = PointToKeyframes(location, ref viewRect);
|
||||||
if (_movingSelectionOffsets == null || _movingSelectionOffsets.Length != _editor._points.Count)
|
if (_movingSelectionOffsets == null || _movingSelectionOffsets.Length != _editor._points.Count)
|
||||||
_movingSelectionOffsets = new Float2[_editor._points.Count];
|
_movingSelectionOffsets = new Float2[_editor._points.Count];
|
||||||
@@ -82,10 +84,17 @@ namespace FlaxEditor.GUI
|
|||||||
|
|
||||||
internal void OnMove(Float2 location)
|
internal void OnMove(Float2 location)
|
||||||
{
|
{
|
||||||
|
// Skip updating keyframes until move actual starts to be meaningful
|
||||||
|
if (Float2.Distance(ref _movingSelectionStartPosLock, ref location) < 1.5f)
|
||||||
|
return;
|
||||||
|
_movingSelectionStartPosLock = Float2.Minimum;
|
||||||
|
|
||||||
var viewRect = _editor._mainPanel.GetClientArea();
|
var viewRect = _editor._mainPanel.GetClientArea();
|
||||||
var locationKeyframes = PointToKeyframes(location, ref viewRect);
|
var locationKeyframes = PointToKeyframes(location, ref viewRect);
|
||||||
var accessor = _editor.Accessor;
|
var accessor = _editor.Accessor;
|
||||||
var components = accessor.GetCurveComponents();
|
var components = accessor.GetCurveComponents();
|
||||||
|
var snapEnabled = Root.GetKey(KeyboardKeys.Control);
|
||||||
|
var snapGrid = snapEnabled ? _editor.GetGridSnap() : Float2.One;
|
||||||
for (var i = 0; i < _editor._points.Count; i++)
|
for (var i = 0; i < _editor._points.Count; i++)
|
||||||
{
|
{
|
||||||
var p = _editor._points[i];
|
var p = _editor._points[i];
|
||||||
@@ -122,7 +131,20 @@ namespace FlaxEditor.GUI
|
|||||||
if (isFirstSelected)
|
if (isFirstSelected)
|
||||||
{
|
{
|
||||||
time = locationKeyframes.X + offset.X;
|
time = locationKeyframes.X + offset.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snapEnabled)
|
||||||
|
{
|
||||||
|
// Snap to the grid
|
||||||
|
var key = new Float2(time, value);
|
||||||
|
key = Float2.SnapToGrid(key, snapGrid);
|
||||||
|
time = key.X;
|
||||||
|
value = key.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp and snap time to the valid range
|
||||||
|
if (isFirstSelected)
|
||||||
|
{
|
||||||
if (_editor.FPS.HasValue)
|
if (_editor.FPS.HasValue)
|
||||||
{
|
{
|
||||||
float fps = _editor.FPS.Value;
|
float fps = _editor.FPS.Value;
|
||||||
@@ -131,8 +153,6 @@ namespace FlaxEditor.GUI
|
|||||||
time = Mathf.Clamp(time, minTime, maxTime);
|
time = Mathf.Clamp(time, minTime, maxTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: snapping keyframes to grid when moving
|
|
||||||
|
|
||||||
_editor.SetKeyframeInternal(p.Index, time, value, p.Component);
|
_editor.SetKeyframeInternal(p.Index, time, value, p.Component);
|
||||||
}
|
}
|
||||||
_editor.UpdateKeyframes();
|
_editor.UpdateKeyframes();
|
||||||
@@ -234,7 +254,11 @@ namespace FlaxEditor.GUI
|
|||||||
var k = _editor.GetKeyframe(_movingTangent.Index);
|
var k = _editor.GetKeyframe(_movingTangent.Index);
|
||||||
var kv = _editor.GetKeyframeValue(k);
|
var kv = _editor.GetKeyframeValue(k);
|
||||||
var value = _editor.Accessor.GetCurveValue(ref kv, _movingTangent.Component);
|
var value = _editor.Accessor.GetCurveValue(ref kv, _movingTangent.Component);
|
||||||
_movingTangent.TangentValue = PointToKeyframes(location, ref viewRect).Y - value;
|
var tangent = PointToKeyframes(location, ref viewRect).Y - value;
|
||||||
|
if (Root.GetKey(KeyboardKeys.Control))
|
||||||
|
tangent = Float2.SnapToGrid(new Float2(0, tangent), _editor.GetGridSnap()).Y; // Snap tangent over Y axis
|
||||||
|
tangent = tangent * _editor.ViewScale.X * 2;
|
||||||
|
_movingTangent.TangentValue = tangent;
|
||||||
_editor.UpdateTangents();
|
_editor.UpdateTangents();
|
||||||
Cursor = CursorType.SizeNS;
|
Cursor = CursorType.SizeNS;
|
||||||
_movedKeyframes = true;
|
_movedKeyframes = true;
|
||||||
@@ -283,6 +307,7 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cache data
|
// Cache data
|
||||||
|
_toggledSelection = false;
|
||||||
_isMovingSelection = false;
|
_isMovingSelection = false;
|
||||||
_isMovingTangent = false;
|
_isMovingTangent = false;
|
||||||
_mousePos = location;
|
_mousePos = location;
|
||||||
@@ -305,13 +330,7 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
if (_leftMouseDown)
|
if (_leftMouseDown)
|
||||||
{
|
{
|
||||||
if (Root.GetKey(KeyboardKeys.Control))
|
if (Root.GetKey(KeyboardKeys.Shift))
|
||||||
{
|
|
||||||
// Toggle selection
|
|
||||||
keyframe.IsSelected = !keyframe.IsSelected;
|
|
||||||
_editor.UpdateTangents();
|
|
||||||
}
|
|
||||||
else if (Root.GetKey(KeyboardKeys.Shift))
|
|
||||||
{
|
{
|
||||||
// Select range
|
// Select range
|
||||||
keyframe.IsSelected = true;
|
keyframe.IsSelected = true;
|
||||||
@@ -335,10 +354,14 @@ namespace FlaxEditor.GUI
|
|||||||
else if (!keyframe.IsSelected)
|
else if (!keyframe.IsSelected)
|
||||||
{
|
{
|
||||||
// Select node
|
// Select node
|
||||||
if (_editor.KeyframesEditorContext != null)
|
if (!Root.GetKey(KeyboardKeys.Control))
|
||||||
_editor.KeyframesEditorContext.OnKeyframesDeselect(_editor);
|
{
|
||||||
else
|
if (_editor.KeyframesEditorContext != null)
|
||||||
_editor.ClearSelection();
|
_editor.KeyframesEditorContext.OnKeyframesDeselect(_editor);
|
||||||
|
else
|
||||||
|
_editor.ClearSelection();
|
||||||
|
}
|
||||||
|
_toggledSelection = true;
|
||||||
keyframe.IsSelected = true;
|
keyframe.IsSelected = true;
|
||||||
_editor.UpdateTangents();
|
_editor.UpdateTangents();
|
||||||
}
|
}
|
||||||
@@ -429,6 +452,12 @@ namespace FlaxEditor.GUI
|
|||||||
else
|
else
|
||||||
OnMoveEnd(location);
|
OnMoveEnd(location);
|
||||||
}
|
}
|
||||||
|
// Toggle selection
|
||||||
|
else if (!_toggledSelection && Root.GetKey(KeyboardKeys.Control) && GetChildAt(location) is KeyframePoint keyframe)
|
||||||
|
{
|
||||||
|
keyframe.IsSelected = !keyframe.IsSelected;
|
||||||
|
_editor.UpdateTangents();
|
||||||
|
}
|
||||||
|
|
||||||
_isMovingSelection = false;
|
_isMovingSelection = false;
|
||||||
_isMovingTangent = false;
|
_isMovingTangent = false;
|
||||||
@@ -514,11 +543,11 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
if (base.OnMouseDoubleClick(location, button))
|
if (base.OnMouseDoubleClick(location, button))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Add keyframe on double click
|
// Add keyframe on double click
|
||||||
var child = GetChildAt(location);
|
var child = GetChildAt(location);
|
||||||
if (child is not KeyframePoint &&
|
if (child is not KeyframePoint &&
|
||||||
child is not TangentPoint &&
|
child is not TangentPoint &&
|
||||||
_editor.KeyframesCount < _editor.MaxKeyframes)
|
_editor.KeyframesCount < _editor.MaxKeyframes)
|
||||||
{
|
{
|
||||||
var viewRect = _editor._mainPanel.GetClientArea();
|
var viewRect = _editor._mainPanel.GetClientArea();
|
||||||
@@ -545,7 +574,7 @@ namespace FlaxEditor.GUI
|
|||||||
var viewRect = _editor._mainPanel.GetClientArea();
|
var viewRect = _editor._mainPanel.GetClientArea();
|
||||||
var locationInKeyframes = PointToKeyframes(location, ref viewRect);
|
var locationInKeyframes = PointToKeyframes(location, ref viewRect);
|
||||||
var locationInEditorBefore = _editor.PointFromKeyframes(locationInKeyframes, ref viewRect);
|
var locationInEditorBefore = _editor.PointFromKeyframes(locationInKeyframes, ref viewRect);
|
||||||
|
|
||||||
// Scale relative to the curve size
|
// Scale relative to the curve size
|
||||||
var scale = new Float2(delta * 0.1f);
|
var scale = new Float2(delta * 0.1f);
|
||||||
_editor._mainPanel.GetDesireClientArea(out var mainPanelArea);
|
_editor._mainPanel.GetDesireClientArea(out var mainPanelArea);
|
||||||
|
|||||||
@@ -163,10 +163,11 @@ namespace FlaxEditor.GUI
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
{
|
{
|
||||||
|
var style = Style.Current;
|
||||||
var rect = new Rectangle(Float2.Zero, Size);
|
var rect = new Rectangle(Float2.Zero, Size);
|
||||||
var color = Editor.ShowCollapsed ? Color.Gray : Editor.Colors[Component];
|
var color = Editor.ShowCollapsed ? style.ForegroundDisabled : Editor.Colors[Component];
|
||||||
if (IsSelected)
|
if (IsSelected)
|
||||||
color = Editor.ContainsFocus ? Color.YellowGreen : Color.Lerp(Color.Gray, Color.YellowGreen, 0.4f);
|
color = Editor.ContainsFocus ? style.SelectionBorder : Color.Lerp(style.ForegroundDisabled, style.SelectionBorder, 0.4f);
|
||||||
if (IsMouseOver)
|
if (IsMouseOver)
|
||||||
color *= 1.1f;
|
color *= 1.1f;
|
||||||
Render2D.FillRectangle(rect, color);
|
Render2D.FillRectangle(rect, color);
|
||||||
@@ -244,14 +245,19 @@ namespace FlaxEditor.GUI
|
|||||||
set => Editor.SetKeyframeTangentInternal(Index, IsIn, Component, value);
|
set => Editor.SetKeyframeTangentInternal(Index, IsIn, Component, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal float TangentOffset => 50.0f / Editor.ViewScale.X;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
{
|
{
|
||||||
|
var style = Style.Current;
|
||||||
|
var thickness = 6.0f / Mathf.Max(Editor.ViewScale.X, 1.0f);
|
||||||
|
var size = Size;
|
||||||
var pointPos = PointFromParent(Point.Center);
|
var pointPos = PointFromParent(Point.Center);
|
||||||
Render2D.DrawLine(Size * 0.5f, pointPos, Color.Gray);
|
Render2D.DrawLine(size * 0.5f, pointPos, style.ForegroundDisabled, thickness);
|
||||||
|
|
||||||
var rect = new Rectangle(Float2.Zero, Size);
|
var rect = new Rectangle(Float2.Zero, size);
|
||||||
var color = Color.MediumVioletRed;
|
var color = style.BorderSelected;
|
||||||
if (IsMouseOver)
|
if (IsMouseOver)
|
||||||
color *= 1.1f;
|
color *= 1.1f;
|
||||||
Render2D.FillRectangle(rect, color);
|
Render2D.FillRectangle(rect, color);
|
||||||
@@ -289,7 +295,7 @@ namespace FlaxEditor.GUI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The curve time/value axes tick steps.
|
/// The curve time/value axes tick steps.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected float[] TickSteps = Utilities.Utils.CurveTickSteps;
|
protected double[] TickSteps = Utilities.Utils.CurveTickSteps;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The curve contents area.
|
/// The curve contents area.
|
||||||
@@ -442,7 +448,7 @@ namespace FlaxEditor.GUI
|
|||||||
_mainPanel = new Panel(ScrollBars.Both)
|
_mainPanel = new Panel(ScrollBars.Both)
|
||||||
{
|
{
|
||||||
ScrollMargin = new Margin(150.0f),
|
ScrollMargin = new Margin(150.0f),
|
||||||
AlwaysShowScrollbars = true,
|
AlwaysShowScrollbars = false,
|
||||||
AnchorPreset = AnchorPresets.StretchAll,
|
AnchorPreset = AnchorPresets.StretchAll,
|
||||||
Offsets = Margin.Zero,
|
Offsets = Margin.Zero,
|
||||||
Parent = this
|
Parent = this
|
||||||
@@ -668,26 +674,82 @@ namespace FlaxEditor.GUI
|
|||||||
OnEditingEnd();
|
OnEditingEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ShowCurve(bool selectedOnly)
|
||||||
|
{
|
||||||
|
if (_points.Count == 0)
|
||||||
|
return;
|
||||||
|
int pass = 1;
|
||||||
|
REDO:
|
||||||
|
|
||||||
|
// Get curve bounds in Keyframes (time and value)
|
||||||
|
Float2 posMin = Float2.Maximum, posMax = Float2.Minimum;
|
||||||
|
// TODO: include bezier curve bounds calculation to handle curve outside the bounds made out of points
|
||||||
|
foreach (var point in _points)
|
||||||
|
{
|
||||||
|
if (selectedOnly && !point.IsSelected)
|
||||||
|
continue;
|
||||||
|
var pos = point.Point;
|
||||||
|
Float2.Min(ref posMin, ref pos, out posMin);
|
||||||
|
Float2.Max(ref posMax, ref pos, out posMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply margin around the area
|
||||||
|
var posMargin = (posMax - posMin) * 0.05f;
|
||||||
|
posMin -= posMargin;
|
||||||
|
posMax += posMargin;
|
||||||
|
|
||||||
|
// Convert from Keyframes to Contents
|
||||||
|
_mainPanel.GetDesireClientArea(out var viewRect);
|
||||||
|
PointFromKeyframesToContents(ref posMin, ref viewRect);
|
||||||
|
PointFromKeyframesToContents(ref posMax, ref viewRect);
|
||||||
|
var tmp = posMin;
|
||||||
|
Float2.Min(ref posMin, ref posMax, out posMin);
|
||||||
|
Float2.Max(ref posMax, ref tmp, out posMax);
|
||||||
|
var contentsSize = posMax - posMin;
|
||||||
|
|
||||||
|
// Convert from Contents to Main Panel
|
||||||
|
posMin = _contents.PointToParent(posMin);
|
||||||
|
posMax = _contents.PointToParent(posMax);
|
||||||
|
tmp = posMin;
|
||||||
|
Float2.Min(ref posMin, ref posMax, out posMin);
|
||||||
|
Float2.Max(ref posMax, ref tmp, out posMax);
|
||||||
|
|
||||||
|
// Update zoom (leave unchanged when focusing a single point)
|
||||||
|
var zoomMask = EnableZoom;
|
||||||
|
if (Mathf.IsZero(posMargin.X))
|
||||||
|
zoomMask &= ~UseMode.Horizontal;
|
||||||
|
if (Mathf.IsZero(posMargin.Y))
|
||||||
|
zoomMask &= ~UseMode.Vertical;
|
||||||
|
ViewScale = ApplyUseModeMask(zoomMask, viewRect.Size / contentsSize, ViewScale);
|
||||||
|
|
||||||
|
// Update scroll (attempt to center the area when it's smaller than the view)
|
||||||
|
Float2 viewOffset = -posMin;
|
||||||
|
Float2 viewSize = _mainPanel.Size;
|
||||||
|
Float2 viewSizeLeft = viewSize - Float2.Clamp(posMax - posMin, Float2.Zero, viewSize);
|
||||||
|
viewOffset += viewSizeLeft * 0.5f;
|
||||||
|
viewOffset = ApplyUseModeMask(EnablePanning, viewOffset, _mainPanel.ViewOffset);
|
||||||
|
_mainPanel.ViewOffset = viewOffset;
|
||||||
|
|
||||||
|
// Do it multiple times so the view offset can be properly calculate once the view scale gets changes
|
||||||
|
if (pass++ <= 2)
|
||||||
|
goto REDO;
|
||||||
|
|
||||||
|
UpdateKeyframes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Focuses the view on the selected keyframes.
|
||||||
|
/// </summary>
|
||||||
|
public void FocusSelection()
|
||||||
|
{
|
||||||
|
// Fallback to showing whole curve if nothing is selected
|
||||||
|
ShowCurve(SelectionCount != 0);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void ShowWholeCurve()
|
public override void ShowWholeCurve()
|
||||||
{
|
{
|
||||||
_mainPanel.GetDesireClientArea(out var mainPanelArea);
|
ShowCurve(false);
|
||||||
ViewScale = ApplyUseModeMask(EnableZoom, mainPanelArea.Size / _contents.Size, ViewScale);
|
|
||||||
Float2 minPos = Float2.Maximum;
|
|
||||||
foreach (var point in _points)
|
|
||||||
{
|
|
||||||
var pos = point.PointToParent(point.Location);
|
|
||||||
Float2.Min(ref minPos, ref pos, out minPos);
|
|
||||||
}
|
|
||||||
var minPosPoint = _contents.PointToParent(ref minPos);
|
|
||||||
var scroll = new Float2(_mainPanel.HScrollBar?.TargetValue ?? 0, _mainPanel.VScrollBar?.TargetValue ?? 0);
|
|
||||||
scroll = ApplyUseModeMask(EnablePanning, minPosPoint, scroll);
|
|
||||||
if (_mainPanel.HScrollBar != null)
|
|
||||||
_mainPanel.HScrollBar.TargetValue = scroll.X;
|
|
||||||
if (_mainPanel.VScrollBar != null)
|
|
||||||
_mainPanel.VScrollBar.TargetValue = scroll.Y;
|
|
||||||
|
|
||||||
UpdateKeyframes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -766,10 +828,7 @@ namespace FlaxEditor.GUI
|
|||||||
point = _contents.PointFromParent(point);
|
point = _contents.PointFromParent(point);
|
||||||
|
|
||||||
// Contents -> Keyframes
|
// Contents -> Keyframes
|
||||||
return new Float2(
|
return PointFromContentsToKeyframes(ref point, ref curveContentAreaBounds);
|
||||||
(point.X + _contents.Location.X) / UnitsPerSecond,
|
|
||||||
(point.Y + _contents.Location.Y - curveContentAreaBounds.Height) / -UnitsPerSecond
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -781,10 +840,7 @@ namespace FlaxEditor.GUI
|
|||||||
protected Float2 PointFromKeyframes(Float2 point, ref Rectangle curveContentAreaBounds)
|
protected Float2 PointFromKeyframes(Float2 point, ref Rectangle curveContentAreaBounds)
|
||||||
{
|
{
|
||||||
// Keyframes -> Contents
|
// Keyframes -> Contents
|
||||||
point = new Float2(
|
PointFromKeyframesToContents(ref point, ref curveContentAreaBounds);
|
||||||
point.X * UnitsPerSecond - _contents.Location.X,
|
|
||||||
point.Y * -UnitsPerSecond + curveContentAreaBounds.Height - _contents.Location.Y
|
|
||||||
);
|
|
||||||
|
|
||||||
// Contents -> Main Panel
|
// Contents -> Main Panel
|
||||||
point = _contents.PointToParent(point);
|
point = _contents.PointToParent(point);
|
||||||
@@ -793,11 +849,27 @@ namespace FlaxEditor.GUI
|
|||||||
return _mainPanel.PointToParent(point);
|
return _mainPanel.PointToParent(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal Float2 PointFromContentsToKeyframes(ref Float2 point, ref Rectangle curveContentAreaBounds)
|
||||||
|
{
|
||||||
|
return new Float2(
|
||||||
|
(point.X + _contents.Location.X) / UnitsPerSecond,
|
||||||
|
(point.Y + _contents.Location.Y - curveContentAreaBounds.Height) / -UnitsPerSecond
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void PointFromKeyframesToContents(ref Float2 point, ref Rectangle curveContentAreaBounds)
|
||||||
|
{
|
||||||
|
point = new Float2(
|
||||||
|
point.X * UnitsPerSecond - _contents.Location.X,
|
||||||
|
point.Y * -UnitsPerSecond + curveContentAreaBounds.Height - _contents.Location.Y
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawAxis(Float2 axis, Rectangle viewRect, float min, float max, float pixelRange)
|
private void DrawAxis(Float2 axis, Rectangle viewRect, float min, float max, float pixelRange)
|
||||||
{
|
{
|
||||||
Utilities.Utils.DrawCurveTicks((float tick, float strength) =>
|
Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
|
||||||
{
|
{
|
||||||
var p = PointFromKeyframes(axis * tick, ref viewRect);
|
var p = PointFromKeyframes(axis * (float)tick, ref viewRect);
|
||||||
|
|
||||||
// Draw line
|
// Draw line
|
||||||
var lineRect = new Rectangle
|
var lineRect = new Rectangle
|
||||||
@@ -820,6 +892,24 @@ namespace FlaxEditor.GUI
|
|||||||
}, TickSteps, ref _tickStrengths, min, max, pixelRange);
|
}, TickSteps, ref _tickStrengths, min, max, pixelRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetupGrid(out Float2 min, out Float2 max, out Float2 pixelRange)
|
||||||
|
{
|
||||||
|
var viewRect = _mainPanel.GetClientArea();
|
||||||
|
var upperLeft = PointToKeyframes(viewRect.Location, ref viewRect);
|
||||||
|
var bottomRight = PointToKeyframes(viewRect.Size, ref viewRect);
|
||||||
|
|
||||||
|
min = Float2.Min(upperLeft, bottomRight);
|
||||||
|
max = Float2.Max(upperLeft, bottomRight);
|
||||||
|
pixelRange = (max - min) * ViewScale * UnitsPerSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Float2 GetGridSnap()
|
||||||
|
{
|
||||||
|
SetupGrid(out var min, out var max, out var pixelRange);
|
||||||
|
return new Float2(Utilities.Utils.GetCurveGridSnap(TickSteps, ref _tickStrengths, min.X, max.X, pixelRange.X),
|
||||||
|
Utilities.Utils.GetCurveGridSnap(TickSteps, ref _tickStrengths, min.Y, max.Y, pixelRange.Y));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Draws the curve.
|
/// Draws the curve.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -849,12 +939,7 @@ namespace FlaxEditor.GUI
|
|||||||
// Draw time and values axes
|
// Draw time and values axes
|
||||||
if (ShowAxes != UseMode.Off)
|
if (ShowAxes != UseMode.Off)
|
||||||
{
|
{
|
||||||
var upperLeft = PointToKeyframes(viewRect.Location, ref viewRect);
|
SetupGrid(out var min, out var max, out var pixelRange);
|
||||||
var bottomRight = PointToKeyframes(viewRect.Size, ref viewRect);
|
|
||||||
|
|
||||||
var min = Float2.Min(upperLeft, bottomRight);
|
|
||||||
var max = Float2.Max(upperLeft, bottomRight);
|
|
||||||
var pixelRange = (max - min) * ViewScale * UnitsPerSecond;
|
|
||||||
|
|
||||||
Render2D.PushClip(ref viewRect);
|
Render2D.PushClip(ref viewRect);
|
||||||
|
|
||||||
@@ -939,7 +1024,7 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
else if (options.FocusSelection.Process(this))
|
else if (options.FocusSelection.Process(this))
|
||||||
{
|
{
|
||||||
ShowWholeCurve();
|
FocusSelection();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2200,7 +2285,7 @@ namespace FlaxEditor.GUI
|
|||||||
|
|
||||||
var tangent = t.TangentValue;
|
var tangent = t.TangentValue;
|
||||||
var direction = t.IsIn ? -1.0f : 1.0f;
|
var direction = t.IsIn ? -1.0f : 1.0f;
|
||||||
var offset = 30.0f;
|
var offset = t.TangentOffset;
|
||||||
var location = GetKeyframePoint(ref k, selectedComponent);
|
var location = GetKeyframePoint(ref k, selectedComponent);
|
||||||
t.Size = KeyframesSize / ViewScale;
|
t.Size = KeyframesSize / ViewScale;
|
||||||
t.Location = new Float2
|
t.Location = new Float2
|
||||||
@@ -2227,6 +2312,18 @@ namespace FlaxEditor.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void SetScaleInternal(ref Float2 scale)
|
||||||
|
{
|
||||||
|
base.SetScaleInternal(ref scale);
|
||||||
|
|
||||||
|
if (!_showCollapsed)
|
||||||
|
{
|
||||||
|
// Refresh keyframes when zooming (their size depends on the scale)
|
||||||
|
UpdateKeyframes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void OnShowContextMenu(ContextMenu.ContextMenu cm, int selectionCount)
|
protected override void OnShowContextMenu(ContextMenu.ContextMenu cm, int selectionCount)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -486,7 +486,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
base.Focus();
|
base.Focus();
|
||||||
|
|
||||||
SelectTab();
|
SelectTab(false);
|
||||||
BringToFront();
|
BringToFront();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using FlaxEditor.Windows;
|
||||||
|
using FlaxEditor.Windows.Assets;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
|
||||||
@@ -55,18 +57,26 @@ namespace FlaxEditor.GUI
|
|||||||
private IsValidDelegate _isValid;
|
private IsValidDelegate _isValid;
|
||||||
private Action<Actor> _selected;
|
private Action<Actor> _selected;
|
||||||
|
|
||||||
private ActorSearchPopup(IsValidDelegate isValid, Action<Actor> selected)
|
private ActorSearchPopup(IsValidDelegate isValid, Action<Actor> selected, CustomEditors.IPresenterOwner context)
|
||||||
{
|
{
|
||||||
_isValid = isValid;
|
_isValid = isValid;
|
||||||
_selected = selected;
|
_selected = selected;
|
||||||
|
|
||||||
ItemClicked += OnItemClicked;
|
ItemClicked += OnItemClicked;
|
||||||
|
|
||||||
// TODO: use async thread to search scenes
|
if (context is PropertiesWindow propertiesWindow || context == null)
|
||||||
for (int i = 0; i < Level.ScenesCount; i++)
|
|
||||||
{
|
{
|
||||||
Find(Level.GetScene(i));
|
// TODO: use async thread to search scenes
|
||||||
|
for (int i = 0; i < Level.ScenesCount; i++)
|
||||||
|
{
|
||||||
|
Find(Level.GetScene(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (context is PrefabWindow prefabWindow)
|
||||||
|
{
|
||||||
|
Find(prefabWindow.Graph.MainActor);
|
||||||
|
}
|
||||||
|
|
||||||
SortItems();
|
SortItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,10 +108,11 @@ namespace FlaxEditor.GUI
|
|||||||
/// <param name="showTargetLocation">The show target location.</param>
|
/// <param name="showTargetLocation">The show target location.</param>
|
||||||
/// <param name="isValid">Event called to check if a given actor item is valid to be used.</param>
|
/// <param name="isValid">Event called to check if a given actor item is valid to be used.</param>
|
||||||
/// <param name="selected">Event called on actor item pick.</param>
|
/// <param name="selected">Event called on actor item pick.</param>
|
||||||
|
/// <param name="context">The presenter owner context (i.e. PrefabWindow, PropertiesWindow).</param>
|
||||||
/// <returns>The dialog.</returns>
|
/// <returns>The dialog.</returns>
|
||||||
public static ActorSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Actor> selected)
|
public static ActorSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Actor> selected, CustomEditors.IPresenterOwner context)
|
||||||
{
|
{
|
||||||
var popup = new ActorSearchPopup(isValid, selected);
|
var popup = new ActorSearchPopup(isValid, selected, context);
|
||||||
popup.Show(showTarget, showTargetLocation);
|
popup.Show(showTarget, showTargetLocation);
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using FlaxEditor.Windows;
|
||||||
|
using FlaxEditor.Windows.Assets;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
@@ -66,18 +68,26 @@ namespace FlaxEditor.GUI
|
|||||||
private IsValidDelegate _isValid;
|
private IsValidDelegate _isValid;
|
||||||
private Action<Script> _selected;
|
private Action<Script> _selected;
|
||||||
|
|
||||||
private ScriptSearchPopup(IsValidDelegate isValid, Action<Script> selected)
|
private ScriptSearchPopup(IsValidDelegate isValid, Action<Script> selected, CustomEditors.IPresenterOwner context)
|
||||||
{
|
{
|
||||||
_isValid = isValid;
|
_isValid = isValid;
|
||||||
_selected = selected;
|
_selected = selected;
|
||||||
|
|
||||||
ItemClicked += OnItemClicked;
|
ItemClicked += OnItemClicked;
|
||||||
|
|
||||||
// TODO: use async thread to search scenes
|
if (context is PropertiesWindow propertiesWindow || context == null)
|
||||||
for (int i = 0; i < Level.ScenesCount; i++)
|
|
||||||
{
|
{
|
||||||
Find(Level.GetScene(i));
|
// TODO: use async thread to search scenes
|
||||||
|
for (int i = 0; i < Level.ScenesCount; i++)
|
||||||
|
{
|
||||||
|
Find(Level.GetScene(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (context is PrefabWindow prefabWindow)
|
||||||
|
{
|
||||||
|
Find(prefabWindow.Graph.MainActor);
|
||||||
|
}
|
||||||
|
|
||||||
SortItems();
|
SortItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,10 +123,11 @@ namespace FlaxEditor.GUI
|
|||||||
/// <param name="showTargetLocation">The show target location.</param>
|
/// <param name="showTargetLocation">The show target location.</param>
|
||||||
/// <param name="isValid">Event called to check if a given script item is valid to be used.</param>
|
/// <param name="isValid">Event called to check if a given script item is valid to be used.</param>
|
||||||
/// <param name="selected">Event called on script item pick.</param>
|
/// <param name="selected">Event called on script item pick.</param>
|
||||||
|
/// <param name="context">The presenter owner context (i.e. PrefabWindow, PropertiesWindow).</param>
|
||||||
/// <returns>The dialog.</returns>
|
/// <returns>The dialog.</returns>
|
||||||
public static ScriptSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Script> selected)
|
public static ScriptSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Script> selected, CustomEditors.IPresenterOwner context)
|
||||||
{
|
{
|
||||||
var popup = new ScriptSearchPopup(isValid, selected);
|
var popup = new ScriptSearchPopup(isValid, selected, context);
|
||||||
popup.Show(showTarget, showTargetLocation);
|
popup.Show(showTarget, showTargetLocation);
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using FlaxEditor.History;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
using CategoryAttribute = FlaxEngine.CategoryAttribute;
|
||||||
|
|
||||||
namespace FlaxEditor.GUI
|
namespace FlaxEditor.GUI
|
||||||
{
|
{
|
||||||
@@ -101,11 +104,26 @@ namespace FlaxEditor.GUI
|
|||||||
if (_isValid(type))
|
if (_isValid(type))
|
||||||
{
|
{
|
||||||
var attributes = type.GetAttributes(true);
|
var attributes = type.GetAttributes(true);
|
||||||
if (attributes.FirstOrDefault(x => x is HideInEditorAttribute || x is System.Runtime.CompilerServices.CompilerGeneratedAttribute) == null)
|
if (IsHideAttributes(attributes))
|
||||||
{
|
{
|
||||||
var mType = type.Type;
|
var mType = type.Type;
|
||||||
if (mType != null && mType.IsValueType && mType.ReflectedType != null && string.Equals(mType.ReflectedType.Name, "<PrivateImplementationDetails>", StringComparison.Ordinal))
|
if (mType != null)
|
||||||
continue;
|
{
|
||||||
|
// Skip if type is compiler-generated
|
||||||
|
if (mType.IsValueType && mType.ReflectedType != null && string.Equals(mType.ReflectedType.Name, "<PrivateImplementationDetails>", StringComparison.Ordinal))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Skip if outer type is hidden
|
||||||
|
if (mType.DeclaringType != null && IsHideAttributes(mType.DeclaringType.GetCustomAttributes(true)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Blacklist some types
|
||||||
|
if (typeof(TypeConverter).IsAssignableFrom(mType) ||
|
||||||
|
typeof(IHistoryAction).IsAssignableFrom(mType) ||
|
||||||
|
(mType.Namespace != null && mType.Namespace.StartsWith("Newtonsoft.Json")))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
AddItem(new TypeItemView(type, attributes));
|
AddItem(new TypeItemView(type, attributes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,6 +131,17 @@ namespace FlaxEditor.GUI
|
|||||||
SortItems();
|
SortItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsHideAttributes(object[] attributes)
|
||||||
|
{
|
||||||
|
return attributes.FirstOrDefault(IsHideAttribute) == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsHideAttribute(object attr)
|
||||||
|
{
|
||||||
|
return attr is HideInEditorAttribute ||
|
||||||
|
attr is System.Runtime.CompilerServices.CompilerGeneratedAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnItemClicked(Item item)
|
private void OnItemClicked(Item item)
|
||||||
{
|
{
|
||||||
_selected(((TypeItemView)item).Type);
|
_selected(((TypeItemView)item).Type);
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
|||||||
class Background : ContainerControl
|
class Background : ContainerControl
|
||||||
{
|
{
|
||||||
private readonly Timeline _timeline;
|
private readonly Timeline _timeline;
|
||||||
private float[] _tickSteps;
|
private double[] _tickSteps;
|
||||||
private float[] _tickStrengths;
|
private float[] _tickStrengths;
|
||||||
private bool _isSelecting;
|
private bool _isSelecting;
|
||||||
private Float2 _selectingStartPos = Float2.Minimum;
|
private Float2 _selectingStartPos = Float2.Minimum;
|
||||||
@@ -176,9 +176,9 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
|||||||
// Draw vertical lines for time axis
|
// Draw vertical lines for time axis
|
||||||
var pixelsInRange = _timeline.Zoom;
|
var pixelsInRange = _timeline.Zoom;
|
||||||
var pixelRange = pixelsInRange * (max - min);
|
var pixelRange = pixelsInRange * (max - min);
|
||||||
var tickRange = Utilities.Utils.DrawCurveTicks((float tick, float strength) =>
|
var tickRange = Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
|
||||||
{
|
{
|
||||||
var time = tick / _timeline.FramesPerSecond;
|
var time = (float)tick / _timeline.FramesPerSecond;
|
||||||
var x = time * zoom + Timeline.StartOffset;
|
var x = time * zoom + Timeline.StartOffset;
|
||||||
var lineColor = style.ForegroundDisabled.RGBMultiplied(0.7f).AlphaMultiplied(strength);
|
var lineColor = style.ForegroundDisabled.RGBMultiplied(0.7f).AlphaMultiplied(strength);
|
||||||
Render2D.FillRectangle(new Rectangle(x - 0.5f, 0, 1.0f, height), lineColor);
|
Render2D.FillRectangle(new Rectangle(x - 0.5f, 0, 1.0f, height), lineColor);
|
||||||
@@ -233,20 +233,20 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
|||||||
int l = Mathf.Clamp(smallestTick + level, 0, _tickSteps.Length - 2);
|
int l = Mathf.Clamp(smallestTick + level, 0, _tickSteps.Length - 2);
|
||||||
var lStep = _tickSteps[l];
|
var lStep = _tickSteps[l];
|
||||||
var lNextStep = _tickSteps[l + 1];
|
var lNextStep = _tickSteps[l + 1];
|
||||||
int startTick = Mathf.FloorToInt(min / lStep);
|
var startTick = Mathd.FloorToInt(min / lStep);
|
||||||
int endTick = Mathf.CeilToInt(max / lStep);
|
var endTick = Mathd.CeilToInt(max / lStep);
|
||||||
Color lineColor = style.Foreground.RGBMultiplied(0.8f).AlphaMultiplied(strength);
|
Color lineColor = style.Foreground.RGBMultiplied(0.8f).AlphaMultiplied(strength);
|
||||||
Color labelColor = style.ForegroundDisabled.AlphaMultiplied(strength);
|
Color labelColor = style.ForegroundDisabled.AlphaMultiplied(strength);
|
||||||
for (int i = startTick; i <= endTick; i++)
|
for (var i = startTick; i <= endTick; i++)
|
||||||
{
|
{
|
||||||
if (l < biggestTick && (i % Mathf.RoundToInt(lNextStep / lStep) == 0))
|
if (l < biggestTick && (i % Mathd.RoundToInt(lNextStep / lStep) == 0))
|
||||||
continue;
|
continue;
|
||||||
var tick = i * lStep;
|
var tick = (decimal)lStep * i;
|
||||||
var time = tick / _timeline.FramesPerSecond;
|
var time = (double)tick / _timeline.FramesPerSecond;
|
||||||
var x = time * zoom + Timeline.StartOffset;
|
var x = (float)time * zoom + Timeline.StartOffset;
|
||||||
|
|
||||||
// Header line
|
// Header line
|
||||||
var lineRect = new Rectangle(x - 0.5f, -verticalLinesHeaderExtend * 0.6f + timeAxisHeaderOffset, 1.0f, verticalLinesHeaderExtend * 0.6f);
|
var lineRect = new Rectangle((float)x - 0.5f, -verticalLinesHeaderExtend * 0.6f + timeAxisHeaderOffset, 1.0f, verticalLinesHeaderExtend * 0.6f);
|
||||||
Render2D.FillRectangle(lineRect, lineColor);
|
Render2D.FillRectangle(lineRect, lineColor);
|
||||||
|
|
||||||
// Time label
|
// Time label
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ using System.Text;
|
|||||||
using FlaxEditor.CustomEditors;
|
using FlaxEditor.CustomEditors;
|
||||||
using FlaxEditor.GUI.ContextMenu;
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
using FlaxEditor.Options;
|
using FlaxEditor.Options;
|
||||||
using FlaxEditor.Scripting;
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Json;
|
using FlaxEngine.Json;
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
|||||||
|
|
||||||
private void OnClickedSelect()
|
private void OnClickedSelect()
|
||||||
{
|
{
|
||||||
ActorSearchPopup.Show(this, PointFromScreen(FlaxEngine.Input.MouseScreenPosition), IsActorValid, SetActor);
|
ActorSearchPopup.Show(this, PointFromScreen(FlaxEngine.Input.MouseScreenPosition), IsActorValid, SetActor, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClickedSelectActor(Image image, MouseButton button)
|
private void OnClickedSelectActor(Image image, MouseButton button)
|
||||||
|
|||||||
@@ -19,12 +19,11 @@ namespace FlaxEditor.Gizmo
|
|||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
private struct Data
|
private struct Data
|
||||||
{
|
{
|
||||||
public Matrix WorldMatrix;
|
|
||||||
public Matrix ViewProjectionMatrix;
|
public Matrix ViewProjectionMatrix;
|
||||||
public Float4 GridColor;
|
public Float4 GridColor;
|
||||||
public Float3 ViewPos;
|
public Float3 ViewPos;
|
||||||
public float Far;
|
public float Far;
|
||||||
public Float3 Padding;
|
public Float3 ViewOrigin;
|
||||||
public float GridSize;
|
public float GridSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +43,7 @@ namespace FlaxEditor.Gizmo
|
|||||||
{
|
{
|
||||||
UseSingleTarget = true;
|
UseSingleTarget = true;
|
||||||
Location = PostProcessEffectLocation.Default;
|
Location = PostProcessEffectLocation.Default;
|
||||||
|
Order = -100000; // Draw before any other editor shapes
|
||||||
_shader = FlaxEngine.Content.LoadAsyncInternal<Shader>("Shaders/Editor/Grid");
|
_shader = FlaxEngine.Content.LoadAsyncInternal<Shader>("Shaders/Editor/Grid");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +62,6 @@ namespace FlaxEditor.Gizmo
|
|||||||
Profiler.BeginEventGPU("Editor Grid");
|
Profiler.BeginEventGPU("Editor Grid");
|
||||||
|
|
||||||
var options = Editor.Instance.Options.Options;
|
var options = Editor.Instance.Options.Options;
|
||||||
Float3 camPos = renderContext.View.WorldPosition;
|
|
||||||
float gridSize = renderContext.View.Far + 20000;
|
float gridSize = renderContext.View.Far + 20000;
|
||||||
|
|
||||||
// Lazy-init resources
|
// Lazy-init resources
|
||||||
@@ -97,10 +96,10 @@ namespace FlaxEditor.Gizmo
|
|||||||
float y = 1.5f; // Add small bias to reduce Z-fighting with geometry at scene origin
|
float y = 1.5f; // Add small bias to reduce Z-fighting with geometry at scene origin
|
||||||
var vertices = new Float3[]
|
var vertices = new Float3[]
|
||||||
{
|
{
|
||||||
new Float3(-gridSize + camPos.X, y, -gridSize + camPos.Z),
|
new Float3(-gridSize, y, -gridSize),
|
||||||
new Float3(gridSize + camPos.X, y, gridSize + camPos.Z),
|
new Float3(gridSize, y, gridSize),
|
||||||
new Float3(-gridSize + camPos.X, y, gridSize + camPos.Z),
|
new Float3(-gridSize, y, gridSize),
|
||||||
new Float3(gridSize + camPos.X, y, -gridSize + camPos.Z),
|
new Float3(gridSize, y, -gridSize),
|
||||||
};
|
};
|
||||||
fixed (Float3* ptr = vertices)
|
fixed (Float3* ptr = vertices)
|
||||||
{
|
{
|
||||||
@@ -113,12 +112,12 @@ namespace FlaxEditor.Gizmo
|
|||||||
{
|
{
|
||||||
var data = new Data();
|
var data = new Data();
|
||||||
Matrix.Multiply(ref renderContext.View.View, ref renderContext.View.Projection, out var viewProjection);
|
Matrix.Multiply(ref renderContext.View.View, ref renderContext.View.Projection, out var viewProjection);
|
||||||
data.WorldMatrix = Matrix.Identity;
|
|
||||||
Matrix.Transpose(ref viewProjection, out data.ViewProjectionMatrix);
|
Matrix.Transpose(ref viewProjection, out data.ViewProjectionMatrix);
|
||||||
data.ViewPos = renderContext.View.WorldPosition;
|
data.ViewPos = renderContext.View.WorldPosition;
|
||||||
data.GridColor = options.Viewport.ViewportGridColor;
|
data.GridColor = options.Viewport.ViewportGridColor;
|
||||||
data.Far = renderContext.View.Far;
|
data.Far = renderContext.View.Far;
|
||||||
data.GridSize = options.Viewport.ViewportGridViewDistance;
|
data.GridSize = options.Viewport.ViewportGridViewDistance;
|
||||||
|
data.ViewOrigin = renderContext.View.Origin;
|
||||||
context.UpdateCB(cb, new IntPtr(&data));
|
context.UpdateCB(cb, new IntPtr(&data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ namespace FlaxEditor.Gizmo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public SelectionOutline()
|
public SelectionOutline()
|
||||||
{
|
{
|
||||||
|
Order = -90000; // Draw before any other editor shapes (except grid gizmo)
|
||||||
|
|
||||||
_outlineMaterial = FlaxEngine.Content.LoadAsyncInternal<Material>("Editor/Gizmo/SelectionOutlineMaterial");
|
_outlineMaterial = FlaxEngine.Content.LoadAsyncInternal<Material>("Editor/Gizmo/SelectionOutlineMaterial");
|
||||||
if (_outlineMaterial)
|
if (_outlineMaterial)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ namespace FlaxEditor.Gizmo
|
|||||||
bool isCenter = _activeAxis == Axis.Center;
|
bool isCenter = _activeAxis == Axis.Center;
|
||||||
renderContext.View.GetWorldMatrix(ref _gizmoWorld, out Matrix world);
|
renderContext.View.GetWorldMatrix(ref _gizmoWorld, out Matrix world);
|
||||||
|
|
||||||
|
const sbyte sortOrder = 100; // Draw after any other editor shapes
|
||||||
const float gizmoModelsScale2RealGizmoSize = 0.075f;
|
const float gizmoModelsScale2RealGizmoSize = 0.075f;
|
||||||
Mesh cubeMesh = _modelCube.LODs[0].Meshes[0];
|
Mesh cubeMesh = _modelCube.LODs[0].Meshes[0];
|
||||||
Mesh sphereMesh = _modelSphere.LODs[0].Meshes[0];
|
Mesh sphereMesh = _modelSphere.LODs[0].Meshes[0];
|
||||||
@@ -136,42 +137,42 @@ namespace FlaxEditor.Gizmo
|
|||||||
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance xAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
||||||
transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3);
|
transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance yAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance yAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
||||||
transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3);
|
transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(Mathf.Pi, out m2);
|
Matrix.RotationX(Mathf.Pi, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance zAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
||||||
transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3);
|
transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// XY plane
|
// XY plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance xyPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xyPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX);
|
||||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3);
|
cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// ZX plane
|
// ZX plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zxPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance zxPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisY);
|
||||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3);
|
cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// YZ plane
|
// YZ plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance yzPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance yzPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisZ);
|
||||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3);
|
cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center sphere
|
// Center sphere
|
||||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -186,22 +187,22 @@ namespace FlaxEditor.Gizmo
|
|||||||
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
|
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
||||||
rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3);
|
rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
||||||
rotationAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m1);
|
rotationAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m1, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(-Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(-Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
||||||
rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3);
|
rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center box
|
// Center box
|
||||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -216,42 +217,42 @@ namespace FlaxEditor.Gizmo
|
|||||||
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref mx1, out m3);
|
Matrix.Multiply(ref m2, ref mx1, out m3);
|
||||||
MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
||||||
scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3);
|
scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
||||||
scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3);
|
scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(Mathf.Pi, out m2);
|
Matrix.RotationX(Mathf.Pi, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
||||||
scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3);
|
scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// XY plane
|
// XY plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance xyPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX);
|
MaterialInstance xyPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX);
|
||||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3);
|
cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// ZX plane
|
// ZX plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance zxPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ);
|
MaterialInstance zxPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ);
|
||||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3);
|
cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// YZ plane
|
// YZ plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
MaterialInstance yzPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY);
|
MaterialInstance yzPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY);
|
||||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3);
|
cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center box
|
// Center box
|
||||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -263,7 +264,7 @@ namespace FlaxEditor.Gizmo
|
|||||||
Transform t = _vertexSnapObject?.Transform ?? _vertexSnapObjectTo.Transform;
|
Transform t = _vertexSnapObject?.Transform ?? _vertexSnapObjectTo.Transform;
|
||||||
Vector3 p = t.LocalToWorld(_vertexSnapObject != null ? _vertexSnapPoint : _vertexSnapPointTo);
|
Vector3 p = t.LocalToWorld(_vertexSnapObject != null ? _vertexSnapPoint : _vertexSnapPointTo);
|
||||||
Matrix matrix = new Transform(p, t.Orientation, new Float3(gizmoModelsScale2RealGizmoSize)).GetWorld();
|
Matrix matrix = new Transform(p, t.Orientation, new Float3(gizmoModelsScale2RealGizmoSize)).GetWorld();
|
||||||
cubeMesh.Draw(ref renderContext, _materialSphere, ref matrix);
|
cubeMesh.Draw(ref renderContext, _materialSphere, ref matrix, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,8 @@ namespace FlaxEditor
|
|||||||
private float _mouseMoveSum;
|
private float _mouseMoveSum;
|
||||||
private UndoMultiBlock _undoBlock;
|
private UndoMultiBlock _undoBlock;
|
||||||
private View _view;
|
private View _view;
|
||||||
private float[] _gridTickSteps = Utilities.Utils.CurveTickSteps, _gridTickStrengths;
|
private double[] _gridTickSteps = Utilities.Utils.CurveTickSteps;
|
||||||
|
private float[] _gridTickStrengths;
|
||||||
private List<Widget> _widgets;
|
private List<Widget> _widgets;
|
||||||
private Widget _activeWidget;
|
private Widget _activeWidget;
|
||||||
|
|
||||||
@@ -564,9 +565,9 @@ namespace FlaxEditor
|
|||||||
var linesColor = style.ForegroundDisabled.RGBMultiplied(0.5f);
|
var linesColor = style.ForegroundDisabled.RGBMultiplied(0.5f);
|
||||||
var labelsColor = style.ForegroundDisabled;
|
var labelsColor = style.ForegroundDisabled;
|
||||||
var labelsSize = 10.0f;
|
var labelsSize = 10.0f;
|
||||||
Utilities.Utils.DrawCurveTicks((float tick, float strength) =>
|
Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
|
||||||
{
|
{
|
||||||
var p = _view.PointToParent(axis * tick);
|
var p = _view.PointToParent(axis * (float)tick);
|
||||||
|
|
||||||
// Draw line
|
// Draw line
|
||||||
var lineRect = new Rectangle
|
var lineRect = new Rectangle
|
||||||
|
|||||||
@@ -504,7 +504,8 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanSetToRoot(Prefab* prefab, Actor* ta
|
|||||||
return false;
|
return false;
|
||||||
const ISerializable::DeserializeStream& newRootData = **newRootDataPtr;
|
const ISerializable::DeserializeStream& newRootData = **newRootDataPtr;
|
||||||
Guid prefabId, prefabObjectID;
|
Guid prefabId, prefabObjectID;
|
||||||
if (JsonTools::GetGuidIfValid(prefabId, newRootData, "PrefabID") && JsonTools::GetGuidIfValid(prefabObjectID, newRootData, "PrefabObjectID"))
|
if (JsonTools::GetGuidIfValid(prefabId, newRootData, "PrefabID") &&
|
||||||
|
JsonTools::GetGuidIfValid(prefabObjectID, newRootData, "PrefabObjectID"))
|
||||||
{
|
{
|
||||||
const auto nestedPrefab = Content::Load<Prefab>(prefabId);
|
const auto nestedPrefab = Content::Load<Prefab>(prefabId);
|
||||||
if (nestedPrefab && nestedPrefab->GetRootObjectId() != prefabObjectID)
|
if (nestedPrefab && nestedPrefab->GetRootObjectId() != prefabObjectID)
|
||||||
@@ -514,21 +515,6 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanSetToRoot(Prefab* prefab, Actor* ta
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_INTERNAL_CALL(void) EditorInternal_GetPrefabNestedObject(Guid* prefabId, Guid* prefabObjectId, Guid* outPrefabId, Guid* outPrefabObjectId)
|
|
||||||
{
|
|
||||||
*outPrefabId = Guid::Empty;
|
|
||||||
*outPrefabObjectId = Guid::Empty;
|
|
||||||
const auto prefab = Content::Load<Prefab>(*prefabId);
|
|
||||||
if (!prefab)
|
|
||||||
return;
|
|
||||||
const ISerializable::DeserializeStream** prefabObjectDataPtr = prefab->ObjectsDataCache.TryGet(*prefabObjectId);
|
|
||||||
if (!prefabObjectDataPtr)
|
|
||||||
return;
|
|
||||||
const ISerializable::DeserializeStream& prefabObjectData = **prefabObjectDataPtr;
|
|
||||||
JsonTools::GetGuidIfValid(*outPrefabId, prefabObjectData, "PrefabID");
|
|
||||||
JsonTools::GetGuidIfValid(*outPrefabObjectId, prefabObjectData, "PrefabObjectID");
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_INTERNAL_CALL(float) EditorInternal_GetAnimationTime(AnimatedModel* animatedModel)
|
DEFINE_INTERNAL_CALL(float) EditorInternal_GetAnimationTime(AnimatedModel* animatedModel)
|
||||||
{
|
{
|
||||||
return animatedModel && animatedModel->GraphInstance.State.Count() == 1 ? animatedModel->GraphInstance.State[0].Animation.TimePosition : 0.0f;
|
return animatedModel && animatedModel->GraphInstance.State.Count() == 1 ? animatedModel->GraphInstance.State[0].Animation.TimePosition : 0.0f;
|
||||||
|
|||||||
@@ -12,11 +12,14 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MException.h"
|
#include "Engine/Scripting/ManagedCLR/MException.h"
|
||||||
#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h"
|
#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h"
|
||||||
#include "Engine/Content/Assets/VisualScript.h"
|
#include "Engine/Content/Assets/VisualScript.h"
|
||||||
|
#include "Engine/Content/Content.h"
|
||||||
#include "Engine/CSG/CSGBuilder.h"
|
#include "Engine/CSG/CSGBuilder.h"
|
||||||
#include "Engine/Engine/CommandLine.h"
|
#include "Engine/Engine/CommandLine.h"
|
||||||
#include "Engine/Renderer/ProbesRenderer.h"
|
#include "Engine/Renderer/ProbesRenderer.h"
|
||||||
#include "Engine/Animations/Graph/AnimGraph.h"
|
#include "Engine/Animations/Graph/AnimGraph.h"
|
||||||
#include "Engine/Core/ObjectsRemovalService.h"
|
#include "Engine/Core/ObjectsRemovalService.h"
|
||||||
|
#include "Engine/Level/Prefabs/Prefab.h"
|
||||||
|
#include "Engine/Serialization/JsonTools.h"
|
||||||
|
|
||||||
ManagedEditor::InternalOptions ManagedEditor::ManagedEditorOptions;
|
ManagedEditor::InternalOptions ManagedEditor::ManagedEditorOptions;
|
||||||
|
|
||||||
@@ -592,6 +595,7 @@ bool ManagedEditor::EvaluateVisualScriptLocal(VisualScript* script, VisualScript
|
|||||||
|
|
||||||
void ManagedEditor::WipeOutLeftoverSceneObjects()
|
void ManagedEditor::WipeOutLeftoverSceneObjects()
|
||||||
{
|
{
|
||||||
|
PROFILE_CPU();
|
||||||
Array<ScriptingObject*> objects = Scripting::GetObjects();
|
Array<ScriptingObject*> objects = Scripting::GetObjects();
|
||||||
bool removedAny = false;
|
bool removedAny = false;
|
||||||
for (ScriptingObject* object : objects)
|
for (ScriptingObject* object : objects)
|
||||||
@@ -613,6 +617,21 @@ void ManagedEditor::WipeOutLeftoverSceneObjects()
|
|||||||
ObjectsRemovalService::Flush();
|
ObjectsRemovalService::Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ManagedEditor::GetPrefabNestedObject(const Guid& prefabId, const Guid& prefabObjectId, Guid& outPrefabId, Guid& outPrefabObjectId)
|
||||||
|
{
|
||||||
|
outPrefabId = Guid::Empty;
|
||||||
|
outPrefabObjectId = Guid::Empty;
|
||||||
|
const auto prefab = Content::Load<Prefab>(prefabId);
|
||||||
|
if (!prefab)
|
||||||
|
return;
|
||||||
|
const ISerializable::DeserializeStream** prefabObjectDataPtr = prefab->ObjectsDataCache.TryGet(prefabObjectId);
|
||||||
|
if (!prefabObjectDataPtr)
|
||||||
|
return;
|
||||||
|
const ISerializable::DeserializeStream& prefabObjectData = **prefabObjectDataPtr;
|
||||||
|
JsonTools::GetGuidIfValid(outPrefabId, prefabObjectData, "PrefabID");
|
||||||
|
JsonTools::GetGuidIfValid(outPrefabObjectId, prefabObjectData, "PrefabObjectID");
|
||||||
|
}
|
||||||
|
|
||||||
void ManagedEditor::OnEditorAssemblyLoaded(MAssembly* assembly)
|
void ManagedEditor::OnEditorAssemblyLoaded(MAssembly* assembly)
|
||||||
{
|
{
|
||||||
ASSERT(!HasManagedInstance());
|
ASSERT(!HasManagedInstance());
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ public:
|
|||||||
API_FUNCTION(Internal) static Array<VisualScriptLocal> GetVisualScriptLocals();
|
API_FUNCTION(Internal) static Array<VisualScriptLocal> GetVisualScriptLocals();
|
||||||
API_FUNCTION(Internal) static bool EvaluateVisualScriptLocal(VisualScript* script, API_PARAM(Ref) VisualScriptLocal& local);
|
API_FUNCTION(Internal) static bool EvaluateVisualScriptLocal(VisualScript* script, API_PARAM(Ref) VisualScriptLocal& local);
|
||||||
API_FUNCTION(Internal) static void WipeOutLeftoverSceneObjects();
|
API_FUNCTION(Internal) static void WipeOutLeftoverSceneObjects();
|
||||||
|
API_FUNCTION(Internal) static void GetPrefabNestedObject(API_PARAM(Ref) const Guid& prefabId, API_PARAM(Ref) const Guid& prefabObjectId, API_PARAM(Out) Guid& outPrefabId, API_PARAM(Out) Guid& outPrefabObjectId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnEditorAssemblyLoaded(MAssembly* assembly);
|
void OnEditorAssemblyLoaded(MAssembly* assembly);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace FlaxEditor.Modules
|
|||||||
private bool _enableEvents;
|
private bool _enableEvents;
|
||||||
private bool _isDuringFastSetup;
|
private bool _isDuringFastSetup;
|
||||||
private bool _rebuildFlag;
|
private bool _rebuildFlag;
|
||||||
|
private bool _rebuildInitFlag;
|
||||||
private int _itemsCreated;
|
private int _itemsCreated;
|
||||||
private int _itemsDeleted;
|
private int _itemsDeleted;
|
||||||
private readonly HashSet<MainContentTreeNode> _dirtyNodes = new HashSet<MainContentTreeNode>();
|
private readonly HashSet<MainContentTreeNode> _dirtyNodes = new HashSet<MainContentTreeNode>();
|
||||||
@@ -61,7 +62,7 @@ namespace FlaxEditor.Modules
|
|||||||
public event Action WorkspaceModified;
|
public event Action WorkspaceModified;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when workspace has will be rebuilt.
|
/// Occurs when workspace will be rebuilt.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action WorkspaceRebuilding;
|
public event Action WorkspaceRebuilding;
|
||||||
|
|
||||||
@@ -88,6 +89,9 @@ namespace FlaxEditor.Modules
|
|||||||
|
|
||||||
// Register AssetItems serialization helper (serialize ref ID only)
|
// Register AssetItems serialization helper (serialize ref ID only)
|
||||||
FlaxEngine.Json.JsonSerializer.Settings.Converters.Add(new AssetItemConverter());
|
FlaxEngine.Json.JsonSerializer.Settings.Converters.Add(new AssetItemConverter());
|
||||||
|
|
||||||
|
ScriptsBuilder.ScriptsReload += OnScriptsReload;
|
||||||
|
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnContentAssetDisposing(Asset asset)
|
private void OnContentAssetDisposing(Asset asset)
|
||||||
@@ -817,6 +821,7 @@ namespace FlaxEditor.Modules
|
|||||||
Profiler.BeginEvent("ContentDatabase.Rebuild");
|
Profiler.BeginEvent("ContentDatabase.Rebuild");
|
||||||
var startTime = Platform.TimeSeconds;
|
var startTime = Platform.TimeSeconds;
|
||||||
_rebuildFlag = false;
|
_rebuildFlag = false;
|
||||||
|
_rebuildInitFlag = false;
|
||||||
_enableEvents = false;
|
_enableEvents = false;
|
||||||
|
|
||||||
// Load all folders
|
// Load all folders
|
||||||
@@ -1230,8 +1235,6 @@ namespace FlaxEditor.Modules
|
|||||||
LoadProjects(Game.Project);
|
LoadProjects(Game.Project);
|
||||||
}
|
}
|
||||||
|
|
||||||
RebuildInternal();
|
|
||||||
|
|
||||||
Editor.ContentImporting.ImportFileEnd += (obj, failed) =>
|
Editor.ContentImporting.ImportFileEnd += (obj, failed) =>
|
||||||
{
|
{
|
||||||
var path = obj.ResultUrl;
|
var path = obj.ResultUrl;
|
||||||
@@ -1239,6 +1242,15 @@ namespace FlaxEditor.Modules
|
|||||||
FlaxEngine.Scripting.InvokeOnUpdate(() => OnImportFileDone(path));
|
FlaxEngine.Scripting.InvokeOnUpdate(() => OnImportFileDone(path));
|
||||||
};
|
};
|
||||||
_enableEvents = true;
|
_enableEvents = true;
|
||||||
|
_rebuildInitFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override void OnEndInit()
|
||||||
|
{
|
||||||
|
// Handle init when project was loaded without scripts loading ()
|
||||||
|
if (_rebuildInitFlag)
|
||||||
|
RebuildInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnImportFileDone(string path)
|
private void OnImportFileDone(string path)
|
||||||
@@ -1313,6 +1325,52 @@ namespace FlaxEditor.Modules
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnScriptsReload()
|
||||||
|
{
|
||||||
|
var enabledEvents = _enableEvents;
|
||||||
|
_enableEvents = false;
|
||||||
|
_isDuringFastSetup = true;
|
||||||
|
var startItems = _itemsCreated;
|
||||||
|
foreach (var project in Projects)
|
||||||
|
{
|
||||||
|
if (project.Content != null)
|
||||||
|
{
|
||||||
|
//Dispose(project.Content.Folder);
|
||||||
|
for (int i = 0; i < project.Content.Folder.Children.Count; i++)
|
||||||
|
{
|
||||||
|
Dispose(project.Content.Folder.Children[i]);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (project.Source != null)
|
||||||
|
{
|
||||||
|
//Dispose(project.Source.Folder);
|
||||||
|
for (int i = 0; i < project.Source.Folder.Children.Count; i++)
|
||||||
|
{
|
||||||
|
Dispose(project.Source.Folder.Children[i]);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ContentProxy> removeProxies = new List<ContentProxy>();
|
||||||
|
foreach (var proxy in Editor.Instance.ContentDatabase.Proxy)
|
||||||
|
{
|
||||||
|
if (proxy.GetType().IsCollectible)
|
||||||
|
removeProxies.Add(proxy);
|
||||||
|
}
|
||||||
|
foreach (var proxy in removeProxies)
|
||||||
|
RemoveProxy(proxy, false);
|
||||||
|
|
||||||
|
_isDuringFastSetup = false;
|
||||||
|
_enableEvents = enabledEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScriptsReloadEnd()
|
||||||
|
{
|
||||||
|
RebuildInternal();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnUpdate()
|
public override void OnUpdate()
|
||||||
{
|
{
|
||||||
@@ -1340,6 +1398,8 @@ namespace FlaxEditor.Modules
|
|||||||
public override void OnExit()
|
public override void OnExit()
|
||||||
{
|
{
|
||||||
FlaxEngine.Content.AssetDisposing -= OnContentAssetDisposing;
|
FlaxEngine.Content.AssetDisposing -= OnContentAssetDisposing;
|
||||||
|
ScriptsBuilder.ScriptsReload -= OnScriptsReload;
|
||||||
|
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||||
|
|
||||||
// Disable events
|
// Disable events
|
||||||
_enableEvents = false;
|
_enableEvents = false;
|
||||||
|
|||||||
@@ -391,6 +391,20 @@ namespace FlaxEditor.Modules
|
|||||||
public override void OnInit()
|
public override void OnInit()
|
||||||
{
|
{
|
||||||
ImportFileEntry.RegisterDefaultTypes();
|
ImportFileEntry.RegisterDefaultTypes();
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScriptsReloadBegin()
|
||||||
|
{
|
||||||
|
// Remove import file types from scripting assemblies
|
||||||
|
List<string> removeFileTypes = new List<string>();
|
||||||
|
foreach (var pair in ImportFileEntry.FileTypes)
|
||||||
|
{
|
||||||
|
if (pair.Value.Method.IsCollectible || (pair.Value.Target != null && pair.Value.Target.GetType().IsCollectible))
|
||||||
|
removeFileTypes.Add(pair.Key);
|
||||||
|
}
|
||||||
|
foreach (var fileType in removeFileTypes)
|
||||||
|
ImportFileEntry.FileTypes.Remove(fileType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -451,6 +465,7 @@ namespace FlaxEditor.Modules
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnExit()
|
public override void OnExit()
|
||||||
{
|
{
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||||
EndWorker();
|
EndWorker();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,33 @@ namespace FlaxEditor.Modules
|
|||||||
Editor.Windows.ContentWin.NewItem(proxy, actor, contentItem => OnPrefabCreated(contentItem, actor, prefabWindow), actor.Name, rename);
|
Editor.Windows.ContentWin.NewItem(proxy, actor, contentItem => OnPrefabCreated(contentItem, actor, prefabWindow), actor.Name, rename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Opens a prefab editor window.
|
||||||
|
/// </summary>
|
||||||
|
public void OpenPrefab(ActorNode actorNode)
|
||||||
|
{
|
||||||
|
if (actorNode != null)
|
||||||
|
OpenPrefab(actorNode.Actor.PrefabID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Opens a prefab editor window.
|
||||||
|
/// </summary>
|
||||||
|
public void OpenPrefab(Guid prefabID = default)
|
||||||
|
{
|
||||||
|
if (prefabID == Guid.Empty)
|
||||||
|
{
|
||||||
|
var selection = Editor.SceneEditing.Selection.Where(x => x is ActorNode actorNode && actorNode.HasPrefabLink).ToList().BuildNodesParents();
|
||||||
|
if (selection.Count == 0 || !((ActorNode)selection[0]).Actor.HasPrefabLink)
|
||||||
|
return;
|
||||||
|
prefabID = ((ActorNode)selection[0]).Actor.PrefabID;
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = Editor.ContentDatabase.Find(prefabID);
|
||||||
|
if (item != null)
|
||||||
|
Editor.ContentEditing.Open(item);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnPrefabCreated(ContentItem contentItem, Actor actor, Windows.Assets.PrefabWindow prefabWindow)
|
private void OnPrefabCreated(ContentItem contentItem, Actor actor, Windows.Assets.PrefabWindow prefabWindow)
|
||||||
{
|
{
|
||||||
if (contentItem is PrefabItem prefabItem)
|
if (contentItem is PrefabItem prefabItem)
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace FlaxEditor.Modules
|
|||||||
: base(editor)
|
: base(editor)
|
||||||
{
|
{
|
||||||
// After editor cache but before the windows
|
// After editor cache but before the windows
|
||||||
InitOrder = -900;
|
InitOrder = -800;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ namespace FlaxEditor.Modules
|
|||||||
internal UIModule(Editor editor)
|
internal UIModule(Editor editor)
|
||||||
: base(editor)
|
: base(editor)
|
||||||
{
|
{
|
||||||
InitOrder = -90;
|
InitOrder = -70;
|
||||||
VisjectSurfaceBackground = FlaxEngine.Content.LoadAsyncInternal<Texture>("Editor/VisjectSurface");
|
VisjectSurfaceBackground = FlaxEngine.Content.LoadAsyncInternal<Texture>("Editor/VisjectSurface");
|
||||||
ColorValueBox.ShowPickColorDialog += ShowPickColorDialog;
|
ColorValueBox.ShowPickColorDialog += ShowPickColorDialog;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ using System.Collections.Generic;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using FlaxEditor.Content;
|
using FlaxEditor.Content;
|
||||||
using FlaxEditor.GUI.Dialogs;
|
using FlaxEditor.GUI.Dialogs;
|
||||||
|
using FlaxEditor.GUI.Docking;
|
||||||
using FlaxEditor.Windows;
|
using FlaxEditor.Windows;
|
||||||
using FlaxEditor.Windows.Assets;
|
using FlaxEditor.Windows.Assets;
|
||||||
using FlaxEditor.Windows.Profiler;
|
using FlaxEditor.Windows.Profiler;
|
||||||
@@ -39,6 +41,7 @@ namespace FlaxEditor.Modules
|
|||||||
|
|
||||||
public DockState DockState;
|
public DockState DockState;
|
||||||
public DockPanel DockedTo;
|
public DockPanel DockedTo;
|
||||||
|
public int DockedTabIndex;
|
||||||
public float? SplitterValue = null;
|
public float? SplitterValue = null;
|
||||||
|
|
||||||
public bool SelectOnShow = false;
|
public bool SelectOnShow = false;
|
||||||
@@ -48,6 +51,8 @@ namespace FlaxEditor.Modules
|
|||||||
public Float2 FloatSize;
|
public Float2 FloatSize;
|
||||||
public Float2 FloatPosition;
|
public Float2 FloatPosition;
|
||||||
|
|
||||||
|
public Guid AssetItemID;
|
||||||
|
|
||||||
// Constructor, to allow for default values
|
// Constructor, to allow for default values
|
||||||
public WindowRestoreData()
|
public WindowRestoreData()
|
||||||
{
|
{
|
||||||
@@ -805,43 +810,64 @@ namespace FlaxEditor.Modules
|
|||||||
Level.SceneSaving += OnSceneSaving;
|
Level.SceneSaving += OnSceneSaving;
|
||||||
Level.SceneUnloaded += OnSceneUnloaded;
|
Level.SceneUnloaded += OnSceneUnloaded;
|
||||||
Level.SceneUnloading += OnSceneUnloading;
|
Level.SceneUnloading += OnSceneUnloading;
|
||||||
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
Editor.ContentDatabase.WorkspaceRebuilt += OnWorkspaceRebuilt;
|
||||||
Editor.StateMachine.StateChanged += OnEditorStateChanged;
|
Editor.StateMachine.StateChanged += OnEditorStateChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void AddToRestore(AssetEditorWindow win)
|
||||||
|
{
|
||||||
|
AddToRestore(win, win.GetType(), new WindowRestoreData
|
||||||
|
{
|
||||||
|
AssetItemID = win.Item.ID,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
internal void AddToRestore(CustomEditorWindow win)
|
internal void AddToRestore(CustomEditorWindow win)
|
||||||
{
|
{
|
||||||
var type = win.GetType();
|
AddToRestore(win.Window, win.GetType(), new WindowRestoreData());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddToRestore(EditorWindow win, Type type, WindowRestoreData winData)
|
||||||
|
{
|
||||||
// Validate if can restore type
|
// Validate if can restore type
|
||||||
var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
|
var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
|
||||||
if (constructor == null || type.IsGenericType)
|
if (constructor == null || type.IsGenericType)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var winData = new WindowRestoreData();
|
var panel = win.ParentDockPanel;
|
||||||
var panel = win.Window.ParentDockPanel;
|
|
||||||
|
|
||||||
// Ensure that this window is only selected following recompilation
|
// Ensure that this window is only selected following recompilation
|
||||||
// if it was the active tab in its dock panel. Otherwise, there is a
|
// if it was the active tab in its dock panel. Otherwise, there is a
|
||||||
// risk of interrupting the user's workflow by potentially selecting
|
// risk of interrupting the user's workflow by potentially selecting
|
||||||
// background tabs.
|
// background tabs.
|
||||||
winData.SelectOnShow = panel.SelectedTab == win.Window;
|
var window = win.RootWindow.Window;
|
||||||
if (panel is FloatWindowDockPanel)
|
winData.SelectOnShow = panel.SelectedTab == win;
|
||||||
|
winData.DockedTabIndex = 0;
|
||||||
|
if (panel is FloatWindowDockPanel && window != null && panel.TabsCount == 1)
|
||||||
{
|
{
|
||||||
winData.DockState = DockState.Float;
|
winData.DockState = DockState.Float;
|
||||||
var window = win.Window.RootWindow.Window;
|
|
||||||
winData.FloatPosition = window.Position;
|
winData.FloatPosition = window.Position;
|
||||||
winData.FloatSize = window.ClientSize;
|
winData.FloatSize = window.ClientSize;
|
||||||
winData.Maximize = window.IsMaximized;
|
winData.Maximize = window.IsMaximized;
|
||||||
winData.Minimize = window.IsMinimized;
|
winData.Minimize = window.IsMinimized;
|
||||||
|
winData.DockedTo = panel;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < panel.Tabs.Count; i++)
|
||||||
|
{
|
||||||
|
if (panel.Tabs[i] == win)
|
||||||
|
{
|
||||||
|
winData.DockedTabIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (panel.TabsCount > 1)
|
if (panel.TabsCount > 1)
|
||||||
{
|
{
|
||||||
winData.DockState = DockState.DockFill;
|
winData.DockState = DockState.DockFill;
|
||||||
winData.DockedTo = panel;
|
winData.DockedTo = panel;
|
||||||
}else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
winData.DockState = panel.TryGetDockState(out var splitterValue);
|
winData.DockState = panel.TryGetDockState(out var splitterValue);
|
||||||
winData.DockedTo = panel.ParentDockPanel;
|
winData.DockedTo = panel.ParentDockPanel;
|
||||||
@@ -853,38 +879,93 @@ namespace FlaxEditor.Modules
|
|||||||
_restoreWindows.Add(winData);
|
_restoreWindows.Add(winData);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnScriptsReloadEnd()
|
private void OnWorkspaceRebuilt()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _restoreWindows.Count; i++)
|
// Go in reverse order to create floating Prefab windows first before docked windows
|
||||||
|
for (int i = _restoreWindows.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var winData = _restoreWindows[i];
|
var winData = _restoreWindows[i];
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var assembly = Utils.GetAssemblyByName(winData.AssemblyName);
|
var assembly = Utils.GetAssemblyByName(winData.AssemblyName);
|
||||||
if (assembly != null)
|
if (assembly == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var type = assembly.GetType(winData.TypeName);
|
||||||
|
if (type == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (type.IsAssignableTo(typeof(AssetEditorWindow)))
|
||||||
{
|
{
|
||||||
var type = assembly.GetType(winData.TypeName);
|
var ctor = type.GetConstructor(new Type[] { typeof(Editor), typeof(AssetItem) });
|
||||||
if (type != null)
|
var assetItem = Editor.ContentDatabase.FindAsset(winData.AssetItemID);
|
||||||
|
var win = (AssetEditorWindow)ctor.Invoke(new object[] { Editor.Instance, assetItem });
|
||||||
|
win.Show(winData.DockState, winData.DockState != DockState.Float ? winData.DockedTo : null, winData.SelectOnShow, winData.SplitterValue);
|
||||||
|
if (winData.DockState == DockState.Float)
|
||||||
{
|
{
|
||||||
var win = (CustomEditorWindow)Activator.CreateInstance(type);
|
var window = win.RootWindow.Window;
|
||||||
win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue);
|
window.Position = winData.FloatPosition;
|
||||||
if (winData.DockState == DockState.Float)
|
if (winData.Maximize)
|
||||||
{
|
{
|
||||||
var window = win.Window.RootWindow.Window;
|
window.Maximize();
|
||||||
window.Position = winData.FloatPosition;
|
}
|
||||||
if (winData.Maximize)
|
else if (winData.Minimize)
|
||||||
{
|
{
|
||||||
window.Maximize();
|
window.Minimize();
|
||||||
}
|
}
|
||||||
else if (winData.Minimize)
|
else
|
||||||
{
|
{
|
||||||
window.Minimize();
|
window.ClientSize = winData.FloatSize;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// Update panel reference in other windows docked to this panel
|
||||||
window.ClientSize = winData.FloatSize;
|
foreach (ref var otherData in CollectionsMarshal.AsSpan(_restoreWindows))
|
||||||
}
|
{
|
||||||
|
if (otherData.DockedTo == winData.DockedTo)
|
||||||
|
otherData.DockedTo = win.ParentDockPanel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var panel = win.ParentDockPanel;
|
||||||
|
int currentTabIndex = 0;
|
||||||
|
for (int pi = 0; pi < panel.TabsCount; pi++)
|
||||||
|
{
|
||||||
|
if (panel.Tabs[pi] == win)
|
||||||
|
{
|
||||||
|
currentTabIndex = pi;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (currentTabIndex > winData.DockedTabIndex)
|
||||||
|
{
|
||||||
|
win.ParentDockPanel.MoveTabLeft(currentTabIndex);
|
||||||
|
currentTabIndex--;
|
||||||
|
}
|
||||||
|
while (currentTabIndex < winData.DockedTabIndex)
|
||||||
|
{
|
||||||
|
win.ParentDockPanel.MoveTabRight(currentTabIndex);
|
||||||
|
currentTabIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var win = (CustomEditorWindow)Activator.CreateInstance(type);
|
||||||
|
win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue);
|
||||||
|
if (winData.DockState == DockState.Float)
|
||||||
|
{
|
||||||
|
var window = win.Window.RootWindow.Window;
|
||||||
|
window.Position = winData.FloatPosition;
|
||||||
|
if (winData.Maximize)
|
||||||
|
{
|
||||||
|
window.Maximize();
|
||||||
|
}
|
||||||
|
else if (winData.Minimize)
|
||||||
|
{
|
||||||
|
window.Minimize();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window.ClientSize = winData.FloatSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -895,6 +976,11 @@ namespace FlaxEditor.Modules
|
|||||||
Editor.LogWarning(string.Format("Failed to restore window {0} (assembly: {1})", winData.TypeName, winData.AssemblyName));
|
Editor.LogWarning(string.Format("Failed to restore window {0} (assembly: {1})", winData.TypeName, winData.AssemblyName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restored windows stole the focus from Editor
|
||||||
|
if (_restoreWindows.Count > 0)
|
||||||
|
Editor.Instance.Windows.MainWindow.Focus();
|
||||||
|
|
||||||
_restoreWindows.Clear();
|
_restoreWindows.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1050,7 +1136,7 @@ namespace FlaxEditor.Modules
|
|||||||
Level.SceneSaving -= OnSceneSaving;
|
Level.SceneSaving -= OnSceneSaving;
|
||||||
Level.SceneUnloaded -= OnSceneUnloaded;
|
Level.SceneUnloaded -= OnSceneUnloaded;
|
||||||
Level.SceneUnloading -= OnSceneUnloading;
|
Level.SceneUnloading -= OnSceneUnloading;
|
||||||
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
Editor.ContentDatabase.WorkspaceRebuilt -= OnWorkspaceRebuilt;
|
||||||
Editor.StateMachine.StateChanged -= OnEditorStateChanged;
|
Editor.StateMachine.StateChanged -= OnEditorStateChanged;
|
||||||
|
|
||||||
// Close main window
|
// Close main window
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using FlaxEditor.CustomEditors;
|
|||||||
using FlaxEditor.CustomEditors.Elements;
|
using FlaxEditor.CustomEditors.Elements;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
using static FlaxEditor.Viewport.EditorViewport;
|
||||||
|
|
||||||
namespace FlaxEditor.Options
|
namespace FlaxEditor.Options
|
||||||
{
|
{
|
||||||
@@ -18,7 +19,7 @@ namespace FlaxEditor.Options
|
|||||||
[HideInEditor]
|
[HideInEditor]
|
||||||
[TypeConverter(typeof(InputBindingConverter))]
|
[TypeConverter(typeof(InputBindingConverter))]
|
||||||
[CustomEditor(typeof(InputBindingEditor))]
|
[CustomEditor(typeof(InputBindingEditor))]
|
||||||
public struct InputBinding
|
public struct InputBinding : IEquatable<InputBinding>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The key to bind.
|
/// The key to bind.
|
||||||
@@ -251,6 +252,40 @@ namespace FlaxEditor.Options
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool Equals(InputBinding other)
|
||||||
|
{
|
||||||
|
return Key == other.Key && Modifier1 == other.Modifier1 && Modifier2 == other.Modifier2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is InputBinding other && Equals(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine((int)Key, (int)Modifier1, (int)Modifier2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compares two values.
|
||||||
|
/// </summary>
|
||||||
|
public static bool operator ==(InputBinding left, InputBinding right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compares two values.
|
||||||
|
/// </summary>
|
||||||
|
public static bool operator !=(InputBinding left, InputBinding right)
|
||||||
|
{
|
||||||
|
return !left.Equals(right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InputBindingConverter : TypeConverter
|
class InputBindingConverter : TypeConverter
|
||||||
@@ -522,5 +557,27 @@ namespace FlaxEditor.Options
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes a specific binding.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="editor">The editor instance.</param>
|
||||||
|
/// <param name="binding">The binding to execute.</param>
|
||||||
|
/// <returns>True if event has been handled, otherwise false.</returns>
|
||||||
|
public bool Invoke(Editor editor, InputBinding binding)
|
||||||
|
{
|
||||||
|
if (binding == new InputBinding())
|
||||||
|
return false;
|
||||||
|
var options = editor.Options.Options.Input;
|
||||||
|
for (int i = 0; i < Bindings.Count; i++)
|
||||||
|
{
|
||||||
|
if (Bindings[i].Binder(options) == binding)
|
||||||
|
{
|
||||||
|
Bindings[i].Callback();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,32 @@ using FlaxEngine;
|
|||||||
|
|
||||||
namespace FlaxEditor.Options
|
namespace FlaxEditor.Options
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Action to perform when a Scene Node receive a double mouse left click.
|
||||||
|
/// </summary>
|
||||||
|
public enum SceneNodeDoubleClick
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles expand/state of the node.
|
||||||
|
/// </summary>
|
||||||
|
Expand,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rename the node.
|
||||||
|
/// </summary>
|
||||||
|
RenameActor,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Focus the object in the viewport.
|
||||||
|
/// </summary>
|
||||||
|
FocusActor,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If possible, open the scene node in an associated Editor (eg. Prefab Editor).
|
||||||
|
/// </summary>
|
||||||
|
OpenPrefab,
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Input editor options data container.
|
/// Input editor options data container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -344,6 +370,10 @@ namespace FlaxEditor.Options
|
|||||||
[EditorDisplay("Interface"), EditorOrder(2020)]
|
[EditorDisplay("Interface"), EditorOrder(2020)]
|
||||||
public InputBinding PreviousTab = new InputBinding(KeyboardKeys.Tab, KeyboardKeys.Control, KeyboardKeys.Shift);
|
public InputBinding PreviousTab = new InputBinding(KeyboardKeys.Tab, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||||
|
|
||||||
|
[DefaultValue(SceneNodeDoubleClick.Expand)]
|
||||||
|
[EditorDisplay("Interface"), EditorOrder(2030)]
|
||||||
|
public SceneNodeDoubleClick DoubleClickSceneNode = SceneNodeDoubleClick.Expand;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ namespace FlaxEditor.Options
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Focus the Game Window. On play mode end restore focus to the previous window.
|
/// Focus the Game Window. On play mode end restore focus to the previous window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
GameWindowThenRestore,
|
GameWindowThenRestore,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -379,6 +379,22 @@ namespace FlaxEditor.Options
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the output log text color for warnings
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(typeof(Color), "1,1,0,1")]
|
||||||
|
[EditorDisplay("Output Log", "Warning Color"), EditorOrder(446), Tooltip("The output log text color for warnings.")]
|
||||||
|
public Color OutputLogWarningTextColor { get; set; } = Color.Yellow;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the output log text color for errors
|
||||||
|
/// </summary>
|
||||||
|
[DefaultValue(typeof(Color), "1,0,0,1")]
|
||||||
|
[EditorDisplay("Output Log", "Error Color"), EditorOrder(445), Tooltip("The output log text color for errors.")]
|
||||||
|
public Color OutputLogErrorTextColor { get; set; } = Color.Red;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether auto-focus output log window on code compilation error.
|
/// Gets or sets a value indicating whether auto-focus output log window on code compilation error.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using FlaxEditor.Content;
|
|||||||
using FlaxEditor.GUI;
|
using FlaxEditor.GUI;
|
||||||
using FlaxEditor.GUI.Drag;
|
using FlaxEditor.GUI.Drag;
|
||||||
using FlaxEditor.GUI.Tree;
|
using FlaxEditor.GUI.Tree;
|
||||||
|
using FlaxEditor.Options;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Utilities;
|
using FlaxEditor.Utilities;
|
||||||
using FlaxEditor.Windows;
|
using FlaxEditor.Windows;
|
||||||
@@ -15,7 +16,6 @@ using FlaxEditor.Windows.Assets;
|
|||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Utilities;
|
using FlaxEngine.Utilities;
|
||||||
using Object = FlaxEngine.Object;
|
|
||||||
|
|
||||||
namespace FlaxEditor.SceneGraph.GUI
|
namespace FlaxEditor.SceneGraph.GUI
|
||||||
{
|
{
|
||||||
@@ -393,7 +393,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts the actor renaming action.
|
/// Starts the actor renaming action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void StartRenaming(EditorWindow window, Panel treePanel = null)
|
public void StartRenaming(EditorWindow window = null, Panel treePanel = null)
|
||||||
{
|
{
|
||||||
// Block renaming during scripts reload
|
// Block renaming during scripts reload
|
||||||
if (Editor.Instance.ProgressReporting.CompileScripts.IsActive)
|
if (Editor.Instance.ProgressReporting.CompileScripts.IsActive)
|
||||||
@@ -461,6 +461,30 @@ namespace FlaxEditor.SceneGraph.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override bool OnMouseDoubleClickHeader(ref Float2 location, MouseButton button)
|
||||||
|
{
|
||||||
|
if (button == MouseButton.Left)
|
||||||
|
{
|
||||||
|
var sceneContext = this.GetSceneContext();
|
||||||
|
switch (Editor.Instance.Options.Options.Input.DoubleClickSceneNode)
|
||||||
|
{
|
||||||
|
case SceneNodeDoubleClick.RenameActor:
|
||||||
|
sceneContext.RenameSelection();
|
||||||
|
return true;
|
||||||
|
case SceneNodeDoubleClick.FocusActor:
|
||||||
|
sceneContext.FocusSelection();
|
||||||
|
return true;
|
||||||
|
case SceneNodeDoubleClick.OpenPrefab:
|
||||||
|
Editor.Instance.Prefabs.OpenPrefab(ActorNode);
|
||||||
|
return true;
|
||||||
|
case SceneNodeDoubleClick.Expand:
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return base.OnMouseDoubleClickHeader(ref location, button);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override DragDropEffect OnDragEnterHeader(DragData data)
|
protected override DragDropEffect OnDragEnterHeader(DragData data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -469,6 +469,7 @@ namespace FlaxEditor.SceneGraph
|
|||||||
{
|
{
|
||||||
ChildNodes[i].OnDispose();
|
ChildNodes[i].OnDispose();
|
||||||
}
|
}
|
||||||
|
ChildNodes.Clear();
|
||||||
|
|
||||||
SceneGraphFactory.Nodes.Remove(ID);
|
SceneGraphFactory.Nodes.Remove(ID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,6 +161,8 @@ namespace FlaxEditor.Surface
|
|||||||
|
|
||||||
private void OnScriptsReloadBegin()
|
private void OnScriptsReloadBegin()
|
||||||
{
|
{
|
||||||
|
_nodesCache.Clear();
|
||||||
|
|
||||||
// Check if any of the nodes comes from the game scripts - those can be reloaded at runtime so prevent crashes
|
// Check if any of the nodes comes from the game scripts - those can be reloaded at runtime so prevent crashes
|
||||||
bool hasTypeFromGameScripts = Editor.Instance.CodeEditing.AnimGraphNodes.HasTypeFromGameScripts;
|
bool hasTypeFromGameScripts = Editor.Instance.CodeEditing.AnimGraphNodes.HasTypeFromGameScripts;
|
||||||
|
|
||||||
|
|||||||
@@ -1182,9 +1182,9 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void DrawEditorBackground(ref Rectangle rect)
|
public override void DrawEditorGrid(ref Rectangle rect)
|
||||||
{
|
{
|
||||||
base.DrawEditorBackground(ref rect);
|
base.DrawEditorGrid(ref rect);
|
||||||
|
|
||||||
// Draw triangulated multi blend space
|
// Draw triangulated multi blend space
|
||||||
var style = Style.Current;
|
var style = Style.Current;
|
||||||
@@ -1195,15 +1195,8 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
else
|
else
|
||||||
Render2D.FillTriangles(_triangles, style.TextBoxBackgroundSelected.AlphaMultiplied(0.6f));
|
Render2D.FillTriangles(_triangles, style.TextBoxBackgroundSelected.AlphaMultiplied(0.6f));
|
||||||
Render2D.DrawTriangles(_triangles, style.Foreground);
|
Render2D.DrawTriangles(_triangles, style.Foreground);
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void DrawEditorGrid(ref Rectangle rect)
|
|
||||||
{
|
|
||||||
base.DrawEditorGrid(ref rect);
|
|
||||||
|
|
||||||
// Highlight selected blend point
|
// Highlight selected blend point
|
||||||
var style = Style.Current;
|
|
||||||
var selectedIndex = _selectedAnimation.SelectedIndex;
|
var selectedIndex = _selectedAnimation.SelectedIndex;
|
||||||
if (selectedIndex != -1 && selectedIndex < _editor.BlendPoints.Count && (ContainsFocus || IsMouseOver))
|
if (selectedIndex != -1 && selectedIndex < _editor.BlendPoints.Count && (ContainsFocus || IsMouseOver))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -87,11 +87,17 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
private class GradientStop : Control
|
private class GradientStop : Control
|
||||||
{
|
{
|
||||||
private bool _isMoving;
|
private bool _isMoving;
|
||||||
|
private float _movedToTime = float.MaxValue;
|
||||||
private Float2 _startMovePos;
|
private Float2 _startMovePos;
|
||||||
|
|
||||||
public ColorGradientNode Node;
|
public ColorGradientNode Node;
|
||||||
public Color Color;
|
public Color Color;
|
||||||
|
|
||||||
|
public void UpdateLocation(float time)
|
||||||
|
{
|
||||||
|
Location = Node._gradient.BottomLeft + new Float2(time * Node._gradient.Width - Width * 0.5f, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Draw()
|
public override void Draw()
|
||||||
{
|
{
|
||||||
@@ -118,6 +124,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
if (button == MouseButton.Left)
|
if (button == MouseButton.Left)
|
||||||
{
|
{
|
||||||
Node.Select(this);
|
Node.Select(this);
|
||||||
|
_movedToTime = float.MaxValue;
|
||||||
_isMoving = true;
|
_isMoving = true;
|
||||||
_startMovePos = location;
|
_startMovePos = location;
|
||||||
StartMouseCapture();
|
StartMouseCapture();
|
||||||
@@ -133,6 +140,12 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
if (button == MouseButton.Left && _isMoving)
|
if (button == MouseButton.Left && _isMoving)
|
||||||
{
|
{
|
||||||
_isMoving = false;
|
_isMoving = false;
|
||||||
|
if (_movedToTime < float.MaxValue)
|
||||||
|
{
|
||||||
|
int index = Node._stops.IndexOf(this);
|
||||||
|
Node.SetStopTime(index, _movedToTime);
|
||||||
|
_movedToTime = float.MaxValue;
|
||||||
|
}
|
||||||
EndMouseCapture();
|
EndMouseCapture();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,9 +172,10 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
if (_isMoving && Float2.DistanceSquared(ref location, ref _startMovePos) > 25.0f)
|
if (_isMoving && Float2.DistanceSquared(ref location, ref _startMovePos) > 25.0f)
|
||||||
{
|
{
|
||||||
_startMovePos = Float2.Minimum;
|
_startMovePos = Float2.Minimum;
|
||||||
var index = Node._stops.IndexOf(this);
|
int index = Node._stops.IndexOf(this);
|
||||||
var time = (PointToParent(location).X - Node._gradient.BottomLeft.X) / Node._gradient.Width;
|
_movedToTime = (PointToParent(location).X - Node._gradient.BottomLeft.X) / Node._gradient.Width;
|
||||||
Node.SetStopTime(index, time);
|
_movedToTime = Node.ClampStopTime(index, _movedToTime);
|
||||||
|
UpdateLocation(_movedToTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnMouseMove(location);
|
base.OnMouseMove(location);
|
||||||
@@ -171,6 +185,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
public override void OnEndMouseCapture()
|
public override void OnEndMouseCapture()
|
||||||
{
|
{
|
||||||
_isMoving = false;
|
_isMoving = false;
|
||||||
|
_movedToTime = float.MaxValue;
|
||||||
|
|
||||||
base.OnEndMouseCapture();
|
base.OnEndMouseCapture();
|
||||||
}
|
}
|
||||||
@@ -223,6 +238,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
Parent = this
|
Parent = this
|
||||||
};
|
};
|
||||||
_timeValue.ValueChanged += OnTimeValueChanged;
|
_timeValue.ValueChanged += OnTimeValueChanged;
|
||||||
|
_timeValue.SlidingEnd += OnTimeValueChanged;
|
||||||
|
|
||||||
_colorValue = new ColorValueBox(Color.Black, _timeValue.Right + 4.0f, controlsLevel)
|
_colorValue = new ColorValueBox(Color.Black, _timeValue.Right + 4.0f, controlsLevel)
|
||||||
{
|
{
|
||||||
@@ -301,8 +317,16 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
|
|
||||||
private void OnTimeValueChanged()
|
private void OnTimeValueChanged()
|
||||||
{
|
{
|
||||||
|
var time = _timeValue.Value;
|
||||||
var index = _stops.IndexOf(_selected);
|
var index = _stops.IndexOf(_selected);
|
||||||
SetStopTime(index, _timeValue.Value);
|
if (_timeValue.IsSliding)
|
||||||
|
{
|
||||||
|
// Preview-only while sliding
|
||||||
|
time = ClampStopTime(index, time);
|
||||||
|
_selected.UpdateLocation(time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetStopTime(index, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnColorValueChanged()
|
private void OnColorValueChanged()
|
||||||
@@ -346,7 +370,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
UpdateStops();
|
UpdateStops();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetStopTime(int index, float time)
|
private float ClampStopTime(int index, float time)
|
||||||
{
|
{
|
||||||
time = Mathf.Saturate(time);
|
time = Mathf.Saturate(time);
|
||||||
if (index != 0)
|
if (index != 0)
|
||||||
@@ -357,6 +381,12 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
time = Mathf.Min(time, (float)Values[1 + index * 2 + 2]);
|
time = Mathf.Min(time, (float)Values[1 + index * 2 + 2]);
|
||||||
}
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetStopTime(int index, float time)
|
||||||
|
{
|
||||||
|
time = ClampStopTime(index, time);
|
||||||
SetValue(1 + index * 2, time);
|
SetValue(1 + index * 2, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,7 +425,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
{
|
{
|
||||||
var stop = _stops[i];
|
var stop = _stops[i];
|
||||||
var time = (float)Values[i * 2 + 1];
|
var time = (float)Values[i * 2 + 1];
|
||||||
stop.Location = _gradient.BottomLeft + new Float2(time * _gradient.Width - stop.Width * 0.5f, 0.0f);
|
stop.UpdateLocation(time);
|
||||||
stop.Color = (Color)Values[i * 2 + 2];
|
stop.Color = (Color)Values[i * 2 + 2];
|
||||||
stop.TooltipText = stop.Color + " at " + time;
|
stop.TooltipText = stop.Color + " at " + time;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace FlaxEditor.Surface
|
|||||||
public BehaviorTreeSurface(IVisjectSurfaceOwner owner, Action onSave, FlaxEditor.Undo undo)
|
public BehaviorTreeSurface(IVisjectSurfaceOwner owner, Action onSave, FlaxEditor.Undo undo)
|
||||||
: base(owner, onSave, undo, CreateStyle())
|
: base(owner, onSave, undo, CreateStyle())
|
||||||
{
|
{
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SurfaceStyle CreateStyle()
|
private static SurfaceStyle CreateStyle()
|
||||||
@@ -35,6 +36,11 @@ namespace FlaxEditor.Surface
|
|||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnScriptsReloadBegin()
|
||||||
|
{
|
||||||
|
_nodesCache.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
private static void DrawBox(Box box)
|
private static void DrawBox(Box box)
|
||||||
{
|
{
|
||||||
var rect = new Rectangle(Float2.Zero, box.Size);
|
var rect = new Rectangle(Float2.Zero, box.Size);
|
||||||
@@ -186,6 +192,7 @@ namespace FlaxEditor.Surface
|
|||||||
{
|
{
|
||||||
if (IsDisposing)
|
if (IsDisposing)
|
||||||
return;
|
return;
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||||
_nodesCache.Wait();
|
_nodesCache.Wait();
|
||||||
|
|
||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
|
|||||||
@@ -415,6 +415,15 @@ namespace FlaxEditor.Surface
|
|||||||
// Init drag handlers
|
// Init drag handlers
|
||||||
DragHandlers.Add(_dragAssets = new DragAssets<DragDropEventArgs>(ValidateDragItem));
|
DragHandlers.Add(_dragAssets = new DragAssets<DragDropEventArgs>(ValidateDragItem));
|
||||||
DragHandlers.Add(_dragParameters = new DragNames<DragDropEventArgs>(SurfaceParameter.DragPrefix, ValidateDragParameter));
|
DragHandlers.Add(_dragParameters = new DragNames<DragDropEventArgs>(SurfaceParameter.DragPrefix, ValidateDragParameter));
|
||||||
|
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScriptsReloadBegin()
|
||||||
|
{
|
||||||
|
_activeVisjectCM = null;
|
||||||
|
_cmPrimaryMenu?.Dispose();
|
||||||
|
_cmPrimaryMenu = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1023,6 +1032,8 @@ namespace FlaxEditor.Surface
|
|||||||
_activeVisjectCM = null;
|
_activeVisjectCM = null;
|
||||||
_cmPrimaryMenu?.Dispose();
|
_cmPrimaryMenu?.Dispose();
|
||||||
|
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||||
|
|
||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,12 @@ namespace FlaxEditor.Surface
|
|||||||
{
|
{
|
||||||
_supportsImplicitCastFromObjectToBoolean = true;
|
_supportsImplicitCastFromObjectToBoolean = true;
|
||||||
DragHandlers.Add(_dragActors = new DragActors(ValidateDragActor));
|
DragHandlers.Add(_dragActors = new DragActors(ValidateDragActor));
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScriptsReloadBegin()
|
||||||
|
{
|
||||||
|
_nodesCache.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateDragActor(ActorNode actor)
|
private bool ValidateDragActor(ActorNode actor)
|
||||||
@@ -631,6 +637,7 @@ namespace FlaxEditor.Surface
|
|||||||
{
|
{
|
||||||
if (IsDisposing)
|
if (IsDisposing)
|
||||||
return;
|
return;
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||||
_nodesCache.Wait();
|
_nodesCache.Wait();
|
||||||
|
|
||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace FlaxEditor.Actions
|
|||||||
public Guid PrefabID;
|
public Guid PrefabID;
|
||||||
public Guid PrefabObjectID;
|
public Guid PrefabObjectID;
|
||||||
|
|
||||||
public unsafe Item(SceneObject obj, List<Item> nestedPrefabLinks)
|
public Item(SceneObject obj, List<Item> nestedPrefabLinks)
|
||||||
{
|
{
|
||||||
ID = obj.ID;
|
ID = obj.ID;
|
||||||
PrefabID = obj.PrefabID;
|
PrefabID = obj.PrefabID;
|
||||||
@@ -33,8 +33,7 @@ namespace FlaxEditor.Actions
|
|||||||
// Check if this object comes from another nested prefab (to break link only from the top-level prefab)
|
// Check if this object comes from another nested prefab (to break link only from the top-level prefab)
|
||||||
Item nested;
|
Item nested;
|
||||||
nested.ID = ID;
|
nested.ID = ID;
|
||||||
fixed (Item* i = &this)
|
Editor.GetPrefabNestedObject(ref PrefabID, ref PrefabObjectID, out nested.PrefabID, out nested.PrefabObjectID);
|
||||||
Editor.Internal_GetPrefabNestedObject(new IntPtr(&i->PrefabID), new IntPtr(&i->PrefabObjectID), new IntPtr(&nested.PrefabID), new IntPtr(&nested.PrefabObjectID));
|
|
||||||
if (nested.PrefabID != Guid.Empty && nested.PrefabObjectID != Guid.Empty)
|
if (nested.PrefabID != Guid.Empty && nested.PrefabObjectID != Guid.Empty)
|
||||||
nestedPrefabLinks.Add(nested);
|
nestedPrefabLinks.Add(nested);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace FlaxEditor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TData">The type of the data. Must have <see cref="SerializableAttribute"/>.</typeparam>
|
/// <typeparam name="TData">The type of the data. Must have <see cref="SerializableAttribute"/>.</typeparam>
|
||||||
/// <seealso cref="FlaxEditor.IUndoAction" />
|
/// <seealso cref="FlaxEditor.IUndoAction" />
|
||||||
[Serializable]
|
[Serializable, HideInEditor]
|
||||||
public abstract class UndoActionBase<TData> : IUndoAction where TData : struct
|
public abstract class UndoActionBase<TData> : IUndoAction where TData : struct
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace FlaxEditor.Utilities;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Units display utilities for Editor.
|
/// Units display utilities for Editor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Units
|
public static class Units
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Factor of units per meter.
|
/// Factor of units per meter.
|
||||||
|
|||||||
@@ -236,19 +236,19 @@ namespace FlaxEditor.Utilities
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time/value axes tick steps for editors with timeline.
|
/// The time/value axes tick steps for editors with timeline.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static readonly float[] CurveTickSteps =
|
internal static readonly double[] CurveTickSteps =
|
||||||
{
|
{
|
||||||
0.0000001f, 0.0000005f, 0.000001f, 0.000005f, 0.00001f,
|
0.0000001, 0.0000005, 0.000001, 0.000005, 0.00001,
|
||||||
0.00005f, 0.0001f, 0.0005f, 0.001f, 0.005f,
|
0.00005, 0.0001, 0.0005, 0.001, 0.005,
|
||||||
0.01f, 0.05f, 0.1f, 0.5f, 1,
|
0.01, 0.05, 0.1, 0.5, 1,
|
||||||
5, 10, 50, 100, 500,
|
5, 10, 50, 100, 500,
|
||||||
1000, 5000, 10000, 50000, 100000,
|
1000, 5000, 10000, 50000, 100000,
|
||||||
500000, 1000000, 5000000, 10000000, 100000000
|
500000, 1000000, 5000000, 10000000, 100000000
|
||||||
};
|
};
|
||||||
|
|
||||||
internal delegate void DrawCurveTick(float tick, float strength);
|
internal delegate void DrawCurveTick(decimal tick, double step, float strength);
|
||||||
|
|
||||||
internal static Int2 DrawCurveTicks(DrawCurveTick drawTick, float[] tickSteps, ref float[] tickStrengths, float min, float max, float pixelRange, float minDistanceBetweenTicks = 20, float maxDistanceBetweenTicks = 60)
|
internal static Int2 DrawCurveTicks(DrawCurveTick drawTick, double[] tickSteps, ref float[] tickStrengths, float min, float max, float pixelRange, float minDistanceBetweenTicks = 20, float maxDistanceBetweenTicks = 60)
|
||||||
{
|
{
|
||||||
if (pixelRange <= Mathf.Epsilon || maxDistanceBetweenTicks <= minDistanceBetweenTicks)
|
if (pixelRange <= Mathf.Epsilon || maxDistanceBetweenTicks <= minDistanceBetweenTicks)
|
||||||
return Int2.Zero;
|
return Int2.Zero;
|
||||||
@@ -262,10 +262,10 @@ namespace FlaxEditor.Utilities
|
|||||||
for (int i = tickSteps.Length - 1; i >= 0; i--)
|
for (int i = tickSteps.Length - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
// Calculate how far apart these modulo tick steps are spaced
|
// Calculate how far apart these modulo tick steps are spaced
|
||||||
float tickSpacing = tickSteps[i] * pixelsInRange;
|
var tickSpacing = tickSteps[i] * pixelsInRange;
|
||||||
|
|
||||||
// Calculate the strength of the tick markers based on the spacing
|
// Calculate the strength of the tick markers based on the spacing
|
||||||
tickStrengths[i] = Mathf.Saturate((tickSpacing - minDistanceBetweenTicks) / (maxDistanceBetweenTicks - minDistanceBetweenTicks));
|
tickStrengths[i] = (float)Mathd.Saturate((tickSpacing - minDistanceBetweenTicks) / (maxDistanceBetweenTicks - minDistanceBetweenTicks));
|
||||||
|
|
||||||
// Beyond threshold the ticks don't get any bigger or fatter
|
// Beyond threshold the ticks don't get any bigger or fatter
|
||||||
if (tickStrengths[i] >= 1)
|
if (tickStrengths[i] >= 1)
|
||||||
@@ -283,7 +283,7 @@ namespace FlaxEditor.Utilities
|
|||||||
// Draw all tick levels
|
// Draw all tick levels
|
||||||
for (int level = 0; level < tickLevels; level++)
|
for (int level = 0; level < tickLevels; level++)
|
||||||
{
|
{
|
||||||
float strength = tickStrengths[smallestTick + level];
|
var strength = tickStrengths[smallestTick + level];
|
||||||
if (strength <= Mathf.Epsilon)
|
if (strength <= Mathf.Epsilon)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -291,20 +291,36 @@ namespace FlaxEditor.Utilities
|
|||||||
int l = Mathf.Clamp(smallestTick + level, 0, tickSteps.Length - 2);
|
int l = Mathf.Clamp(smallestTick + level, 0, tickSteps.Length - 2);
|
||||||
var lStep = tickSteps[l];
|
var lStep = tickSteps[l];
|
||||||
var lNextStep = tickSteps[l + 1];
|
var lNextStep = tickSteps[l + 1];
|
||||||
int startTick = Mathf.FloorToInt(min / lStep);
|
var startTick = Mathd.FloorToInt(min / lStep);
|
||||||
int endTick = Mathf.CeilToInt(max / lStep);
|
var endTick = Mathd.CeilToInt(max / lStep);
|
||||||
for (int i = startTick; i <= endTick; i++)
|
for (var i = startTick; i <= endTick; i++)
|
||||||
{
|
{
|
||||||
if (l < biggestTick && (i % Mathf.RoundToInt(lNextStep / lStep) == 0))
|
if (l < biggestTick && (i % Mathd.RoundToInt(lNextStep / lStep) == 0))
|
||||||
continue;
|
continue;
|
||||||
var tick = i * lStep;
|
var tick = (decimal)lStep * i;
|
||||||
drawTick(tick, strength);
|
drawTick(tick, lStep, strength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Int2(smallestTick, biggestTick);
|
return new Int2(smallestTick, biggestTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static float GetCurveGridSnap(double[] tickSteps, ref float[] tickStrengths, float min, float max, float pixelRange, float minDistanceBetweenTicks = 20, float maxDistanceBetweenTicks = 60)
|
||||||
|
{
|
||||||
|
double gridStep = 0; // No grid
|
||||||
|
float gridWeight = 0.0f;
|
||||||
|
DrawCurveTicks((decimal tick, double step, float strength) =>
|
||||||
|
{
|
||||||
|
// Find the smallest grid step that has meaningful strength (it's the most visible to the user)
|
||||||
|
if (strength > gridWeight && (step < gridStep || gridStep <= 0.0) && strength > 0.5f)
|
||||||
|
{
|
||||||
|
gridStep = Math.Abs(step);
|
||||||
|
gridWeight = strength;
|
||||||
|
}
|
||||||
|
}, tickSteps, ref tickStrengths, min, max, pixelRange, minDistanceBetweenTicks, maxDistanceBetweenTicks);
|
||||||
|
return (float)gridStep;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the specified path string contains any invalid character.
|
/// Determines whether the specified path string contains any invalid character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -1528,5 +1544,12 @@ namespace FlaxEditor.Utilities
|
|||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static ISceneContextWindow GetSceneContext(this Control c)
|
||||||
|
{
|
||||||
|
while (c != null && !(c is ISceneContextWindow))
|
||||||
|
c = c.Parent;
|
||||||
|
return c as ISceneContextWindow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using FlaxEditor.Content;
|
using FlaxEditor.Content;
|
||||||
using FlaxEditor.Gizmo;
|
using FlaxEditor.Gizmo;
|
||||||
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
using FlaxEditor.SceneGraph;
|
using FlaxEditor.SceneGraph;
|
||||||
using FlaxEditor.Scripting;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.Viewport.Cameras;
|
using FlaxEditor.Viewport.Cameras;
|
||||||
using FlaxEditor.Viewport.Previews;
|
using FlaxEditor.Viewport.Previews;
|
||||||
|
using FlaxEditor.Viewport.Widgets;
|
||||||
using FlaxEditor.Windows.Assets;
|
using FlaxEditor.Windows.Assets;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
@@ -44,7 +46,7 @@ namespace FlaxEditor.Viewport
|
|||||||
private sealed class PrefabUIEditorRoot : UIEditorRoot
|
private sealed class PrefabUIEditorRoot : UIEditorRoot
|
||||||
{
|
{
|
||||||
private readonly PrefabWindowViewport _viewport;
|
private readonly PrefabWindowViewport _viewport;
|
||||||
private bool UI => _viewport._hasUILinkedCached;
|
private bool UI => _viewport.ShowUI;
|
||||||
|
|
||||||
public PrefabUIEditorRoot(PrefabWindowViewport viewport)
|
public PrefabUIEditorRoot(PrefabWindowViewport viewport)
|
||||||
: base(true)
|
: base(true)
|
||||||
@@ -67,8 +69,78 @@ namespace FlaxEditor.Viewport
|
|||||||
private PrefabSpritesRenderer _spritesRenderer;
|
private PrefabSpritesRenderer _spritesRenderer;
|
||||||
private IntPtr _tempDebugDrawContext;
|
private IntPtr _tempDebugDrawContext;
|
||||||
|
|
||||||
private bool _hasUILinkedCached;
|
|
||||||
private PrefabUIEditorRoot _uiRoot;
|
private PrefabUIEditorRoot _uiRoot;
|
||||||
|
private bool _showUI = false;
|
||||||
|
|
||||||
|
private ContextMenuButton _uiModeButton;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event fired when the UI Mode is toggled.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<bool> UIModeToggled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// set the initial UI mod
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">the initial ShowUI value</param>
|
||||||
|
public void SetInitialUIMode(bool value)
|
||||||
|
{
|
||||||
|
ShowUI = value;
|
||||||
|
_uiModeButton.Checked = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to show the UI mode or not.
|
||||||
|
/// </summary>
|
||||||
|
public bool ShowUI
|
||||||
|
{
|
||||||
|
get => _showUI;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_showUI = value;
|
||||||
|
if (_showUI)
|
||||||
|
{
|
||||||
|
// UI widget
|
||||||
|
Gizmos.Active = null;
|
||||||
|
ViewportCamera = new UIEditorCamera { UIEditor = _uiRoot };
|
||||||
|
|
||||||
|
// Hide 3D visuals
|
||||||
|
ShowEditorPrimitives = false;
|
||||||
|
ShowDefaultSceneActors = false;
|
||||||
|
ShowDebugDraw = false;
|
||||||
|
|
||||||
|
// Show whole UI on startup
|
||||||
|
var canvas = (CanvasRootControl)_uiParentLink.Children.FirstOrDefault(x => x is CanvasRootControl);
|
||||||
|
if (canvas != null)
|
||||||
|
ViewportCamera.ShowActor(canvas.Canvas);
|
||||||
|
else if (Instance is UIControl)
|
||||||
|
ViewportCamera.ShowActor(Instance);
|
||||||
|
_uiRoot.Visible = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Generic prefab
|
||||||
|
Gizmos.Active = TransformGizmo;
|
||||||
|
ViewportCamera = new FPSCamera();
|
||||||
|
_uiRoot.Visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update default components usage
|
||||||
|
bool defaultFeatures = !_showUI;
|
||||||
|
_disableInputUpdate = _showUI;
|
||||||
|
_spritesRenderer.Enabled = defaultFeatures;
|
||||||
|
SelectionOutline.Enabled = defaultFeatures;
|
||||||
|
_showDefaultSceneButton.Visible = defaultFeatures;
|
||||||
|
_cameraWidget.Visible = defaultFeatures;
|
||||||
|
_cameraButton.Visible = defaultFeatures;
|
||||||
|
_orthographicModeButton.Visible = defaultFeatures;
|
||||||
|
Task.Enabled = defaultFeatures;
|
||||||
|
UseAutomaticTaskManagement = defaultFeatures;
|
||||||
|
ShowDefaultSceneActors = defaultFeatures;
|
||||||
|
TintColor = defaultFeatures ? Color.White : Color.Transparent;
|
||||||
|
UIModeToggled?.Invoke(_showUI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Drag and drop handlers
|
/// Drag and drop handlers
|
||||||
@@ -138,6 +210,11 @@ namespace FlaxEditor.Viewport
|
|||||||
_uiRoot.IndexInParent = 0; // Move viewport down below other widgets in the viewport
|
_uiRoot.IndexInParent = 0; // Move viewport down below other widgets in the viewport
|
||||||
_uiParentLink = _uiRoot.UIRoot;
|
_uiParentLink = _uiRoot.UIRoot;
|
||||||
|
|
||||||
|
// UI mode buton
|
||||||
|
_uiModeButton = ViewWidgetShowMenu.AddButton("UI Mode", (button) => ShowUI = button.Checked);
|
||||||
|
_uiModeButton.AutoCheck = true;
|
||||||
|
_uiModeButton.VisibleChanged += control => (control as ContextMenuButton).Checked = ShowUI;
|
||||||
|
|
||||||
EditorGizmoViewport.AddGizmoViewportWidgets(this, TransformGizmo);
|
EditorGizmoViewport.AddGizmoViewportWidgets(this, TransformGizmo);
|
||||||
|
|
||||||
// Setup input actions
|
// Setup input actions
|
||||||
@@ -146,58 +223,8 @@ namespace FlaxEditor.Viewport
|
|||||||
SetUpdate(ref _update, OnUpdate);
|
SetUpdate(ref _update, OnUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the viewport's gizmos, especially to toggle between 3D and UI editing modes.
|
|
||||||
/// </summary>
|
|
||||||
internal void UpdateGizmoMode()
|
|
||||||
{
|
|
||||||
// Skip if gizmo mode was unmodified
|
|
||||||
if (_hasUILinked == _hasUILinkedCached)
|
|
||||||
return;
|
|
||||||
_hasUILinkedCached = _hasUILinked;
|
|
||||||
|
|
||||||
if (_hasUILinked)
|
|
||||||
{
|
|
||||||
// UI widget
|
|
||||||
Gizmos.Active = null;
|
|
||||||
ViewportCamera = new UIEditorCamera { UIEditor = _uiRoot };
|
|
||||||
|
|
||||||
// Hide 3D visuals
|
|
||||||
ShowEditorPrimitives = false;
|
|
||||||
ShowDefaultSceneActors = false;
|
|
||||||
ShowDebugDraw = false;
|
|
||||||
|
|
||||||
// Show whole UI on startup
|
|
||||||
var canvas = (CanvasRootControl)_uiParentLink.Children.FirstOrDefault(x => x is CanvasRootControl);
|
|
||||||
if (canvas != null)
|
|
||||||
ViewportCamera.ShowActor(canvas.Canvas);
|
|
||||||
else if (Instance is UIControl)
|
|
||||||
ViewportCamera.ShowActor(Instance);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Generic prefab
|
|
||||||
Gizmos.Active = TransformGizmo;
|
|
||||||
ViewportCamera = new FPSCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update default components usage
|
|
||||||
bool defaultFeatures = !_hasUILinked;
|
|
||||||
_disableInputUpdate = _hasUILinked;
|
|
||||||
_spritesRenderer.Enabled = defaultFeatures;
|
|
||||||
SelectionOutline.Enabled = defaultFeatures;
|
|
||||||
_showDefaultSceneButton.Visible = defaultFeatures;
|
|
||||||
_cameraWidget.Visible = defaultFeatures;
|
|
||||||
_cameraButton.Visible = defaultFeatures;
|
|
||||||
_orthographicModeButton.Visible = defaultFeatures;
|
|
||||||
Task.Enabled = defaultFeatures;
|
|
||||||
UseAutomaticTaskManagement = defaultFeatures;
|
|
||||||
TintColor = defaultFeatures ? Color.White : Color.Transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnUpdate(float deltaTime)
|
private void OnUpdate(float deltaTime)
|
||||||
{
|
{
|
||||||
UpdateGizmoMode();
|
|
||||||
for (int i = 0; i < Gizmos.Count; i++)
|
for (int i = 0; i < Gizmos.Count; i++)
|
||||||
{
|
{
|
||||||
Gizmos[i].Update(deltaTime);
|
Gizmos[i].Update(deltaTime);
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
InputActions.Add(options => options.Save, Save);
|
InputActions.Add(options => options.Save, Save);
|
||||||
|
|
||||||
UpdateTitle();
|
UpdateTitle();
|
||||||
|
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -151,6 +153,8 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnDestroy()
|
public override void OnDestroy()
|
||||||
{
|
{
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||||
|
|
||||||
if (_item != null)
|
if (_item != null)
|
||||||
{
|
{
|
||||||
// Ensure to remove linkage to the item
|
// Ensure to remove linkage to the item
|
||||||
@@ -160,6 +164,15 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected virtual void OnScriptsReloadBegin()
|
||||||
|
{
|
||||||
|
if (!IsHidden)
|
||||||
|
{
|
||||||
|
Editor.Instance.Windows.AddToRestore(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region IEditable Implementation
|
#region IEditable Implementation
|
||||||
|
|
||||||
private bool _isEdited;
|
private bool _isEdited;
|
||||||
|
|||||||
@@ -268,8 +268,11 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
UpdateKnowledge();
|
UpdateKnowledge();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnScriptsReloadBegin()
|
/// <inheritdoc />
|
||||||
|
protected override void OnScriptsReloadBegin()
|
||||||
{
|
{
|
||||||
|
base.OnScriptsReloadBegin();
|
||||||
|
|
||||||
// TODO: impl hot-reload for BT to nicely refresh state (save asset, clear undo/properties, reload surface)
|
// TODO: impl hot-reload for BT to nicely refresh state (save asset, clear undo/properties, reload surface)
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
ViewportCamera = new FPSCamera(),
|
ViewportCamera = new FPSCamera(),
|
||||||
Parent = _split.Panel1
|
Parent = _split.Panel1
|
||||||
};
|
};
|
||||||
_preview.Task.ViewFlags &= ~ViewFlags.Sky & ~ViewFlags.Bloom;
|
_preview.Task.ViewFlags &= ~ViewFlags.Sky & ~ViewFlags.Bloom & ~ViewFlags.EyeAdaptation;
|
||||||
|
|
||||||
// Asset properties
|
// Asset properties
|
||||||
_propertiesPresenter = new CustomEditorPresenter(null);
|
_propertiesPresenter = new CustomEditorPresenter(null);
|
||||||
|
|||||||
@@ -124,8 +124,10 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
UpdateToolstrip();
|
UpdateToolstrip();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnScriptsReloadBegin()
|
/// <inheritdoc />
|
||||||
|
protected override void OnScriptsReloadBegin()
|
||||||
{
|
{
|
||||||
|
base.OnScriptsReloadBegin();
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using FlaxEditor.Content;
|
using FlaxEditor.Content;
|
||||||
using FlaxEditor.GUI.ContextMenu;
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
using FlaxEditor.GUI.Drag;
|
using FlaxEditor.GUI.Drag;
|
||||||
@@ -86,7 +85,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
{
|
{
|
||||||
return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
|
return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool ValidateDragControlType(ScriptType controlType)
|
private static bool ValidateDragControlType(ScriptType controlType)
|
||||||
{
|
{
|
||||||
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
|
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
|
||||||
@@ -171,7 +170,8 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
var actor = item.OnEditorDrop(this);
|
var actor = item.OnEditorDrop(this);
|
||||||
actor.Name = item.ShortName;
|
actor.Name = item.ShortName;
|
||||||
_window.Spawn(actor);
|
_window.Spawn(actor);
|
||||||
var graphNode = _window.Graph.Root.Find(actor);;
|
var graphNode = _window.Graph.Root.Find(actor);
|
||||||
|
;
|
||||||
if (graphNode != null)
|
if (graphNode != null)
|
||||||
graphNodes.Add(graphNode);
|
graphNodes.Add(graphNode);
|
||||||
}
|
}
|
||||||
@@ -235,7 +235,8 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
}
|
}
|
||||||
actor.Name = actorType.Name;
|
actor.Name = actorType.Name;
|
||||||
_window.Spawn(actor);
|
_window.Spawn(actor);
|
||||||
var graphNode = _window.Graph.Root.Find(actor);;
|
var graphNode = _window.Graph.Root.Find(actor);
|
||||||
|
;
|
||||||
if (graphNode != null)
|
if (graphNode != null)
|
||||||
graphNodes.Add(graphNode);
|
graphNodes.Add(graphNode);
|
||||||
}
|
}
|
||||||
@@ -290,7 +291,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
|
|
||||||
// Basic editing options
|
// Basic editing options
|
||||||
|
|
||||||
var b = contextMenu.AddButton("Rename", Rename);
|
var b = contextMenu.AddButton("Rename", RenameSelection);
|
||||||
b.Enabled = isSingleActorSelected;
|
b.Enabled = isSingleActorSelected;
|
||||||
|
|
||||||
b = contextMenu.AddButton("Duplicate", Duplicate);
|
b = contextMenu.AddButton("Duplicate", Duplicate);
|
||||||
@@ -414,7 +415,8 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
contextMenu.Show(parent, location);
|
contextMenu.Show(parent, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Rename()
|
/// <inheritdoc />
|
||||||
|
public void RenameSelection()
|
||||||
{
|
{
|
||||||
var selection = Selection;
|
var selection = Selection;
|
||||||
if (selection.Count != 0 && selection[0] is ActorNode actor)
|
if (selection.Count != 0 && selection[0] is ActorNode actor)
|
||||||
@@ -425,6 +427,12 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void FocusSelection()
|
||||||
|
{
|
||||||
|
_viewport.FocusSelection();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spawns the specified actor to the prefab (adds actor to root).
|
/// Spawns the specified actor to the prefab (adds actor to root).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -468,7 +476,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
|
|
||||||
// Spawn it
|
// Spawn it
|
||||||
Spawn(actor);
|
Spawn(actor);
|
||||||
Rename();
|
RenameSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="Prefab" />
|
/// <seealso cref="Prefab" />
|
||||||
/// <seealso cref="FlaxEditor.Windows.Assets.AssetEditorWindow" />
|
/// <seealso cref="FlaxEditor.Windows.Assets.AssetEditorWindow" />
|
||||||
public sealed partial class PrefabWindow : AssetEditorWindowBase<Prefab>, IPresenterOwner
|
public sealed partial class PrefabWindow : AssetEditorWindowBase<Prefab>, IPresenterOwner, ISceneContextWindow
|
||||||
{
|
{
|
||||||
private readonly SplitPanel _split1;
|
private readonly SplitPanel _split1;
|
||||||
private readonly SplitPanel _split2;
|
private readonly SplitPanel _split2;
|
||||||
@@ -194,7 +194,6 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
|
|
||||||
Editor.Prefabs.PrefabApplied += OnPrefabApplied;
|
Editor.Prefabs.PrefabApplied += OnPrefabApplied;
|
||||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
|
||||||
|
|
||||||
// Setup input actions
|
// Setup input actions
|
||||||
InputActions.Add(options => options.Undo, () =>
|
InputActions.Add(options => options.Undo, () =>
|
||||||
@@ -212,8 +211,8 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
InputActions.Add(options => options.Paste, Paste);
|
InputActions.Add(options => options.Paste, Paste);
|
||||||
InputActions.Add(options => options.Duplicate, Duplicate);
|
InputActions.Add(options => options.Duplicate, Duplicate);
|
||||||
InputActions.Add(options => options.Delete, Delete);
|
InputActions.Add(options => options.Delete, Delete);
|
||||||
InputActions.Add(options => options.Rename, Rename);
|
InputActions.Add(options => options.Rename, RenameSelection);
|
||||||
InputActions.Add(options => options.FocusSelection, _viewport.FocusSelection);
|
InputActions.Add(options => options.FocusSelection, FocusSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -287,8 +286,10 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnScriptsReloadBegin()
|
/// <inheritdoc />
|
||||||
|
protected override void OnScriptsReloadBegin()
|
||||||
{
|
{
|
||||||
|
base.OnScriptsReloadBegin();
|
||||||
_isScriptsReloading = true;
|
_isScriptsReloading = true;
|
||||||
|
|
||||||
if (_asset == null || !_asset.IsLoaded)
|
if (_asset == null || !_asset.IsLoaded)
|
||||||
@@ -316,19 +317,8 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
Graph.MainActor = null;
|
Graph.MainActor = null;
|
||||||
_viewport.Prefab = null;
|
_viewport.Prefab = null;
|
||||||
_undo?.Clear(); // TODO: maybe don't clear undo?
|
_undo?.Clear(); // TODO: maybe don't clear undo?
|
||||||
}
|
|
||||||
|
|
||||||
private void OnScriptsReloadEnd()
|
Close();
|
||||||
{
|
|
||||||
_isScriptsReloading = false;
|
|
||||||
|
|
||||||
if (_asset == null || !_asset.IsLoaded)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Restore
|
|
||||||
OnPrefabOpened();
|
|
||||||
_undo.Clear();
|
|
||||||
ClearEditedFlag();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUndoEvent(IUndoAction action)
|
private void OnUndoEvent(IUndoAction action)
|
||||||
@@ -355,13 +345,22 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
private void OnPrefabOpened()
|
private void OnPrefabOpened()
|
||||||
{
|
{
|
||||||
_viewport.Prefab = _asset;
|
_viewport.Prefab = _asset;
|
||||||
_viewport.UpdateGizmoMode();
|
if (Editor.ProjectCache.TryGetCustomData($"UIMode:{_asset.ID}", out bool value))
|
||||||
|
_viewport.SetInitialUIMode(value);
|
||||||
|
else
|
||||||
|
_viewport.SetInitialUIMode(_viewport._hasUILinked);
|
||||||
|
_viewport.UIModeToggled += OnUIModeToggled;
|
||||||
Graph.MainActor = _viewport.Instance;
|
Graph.MainActor = _viewport.Instance;
|
||||||
Selection.Clear();
|
Selection.Clear();
|
||||||
Select(Graph.Main);
|
Select(Graph.Main);
|
||||||
Graph.Root.TreeNode.Expand(true);
|
Graph.Root.TreeNode.Expand(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnUIModeToggled(bool value)
|
||||||
|
{
|
||||||
|
Editor.ProjectCache.SetCustomData($"UIMode:{_asset.ID}", value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Save()
|
public override void Save()
|
||||||
{
|
{
|
||||||
@@ -538,7 +537,6 @@ namespace FlaxEditor.Windows.Assets
|
|||||||
{
|
{
|
||||||
Editor.Prefabs.PrefabApplied -= OnPrefabApplied;
|
Editor.Prefabs.PrefabApplied -= OnPrefabApplied;
|
||||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||||
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
|
||||||
|
|
||||||
_undo.Dispose();
|
_undo.Dispose();
|
||||||
Graph.Dispose();
|
Graph.Dispose();
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace FlaxEditor.Windows
|
|||||||
private const string ProjectDataLastViewedFolder = "LastViewedFolder";
|
private const string ProjectDataLastViewedFolder = "LastViewedFolder";
|
||||||
private bool _isWorkspaceDirty;
|
private bool _isWorkspaceDirty;
|
||||||
private string _workspaceRebuildLocation;
|
private string _workspaceRebuildLocation;
|
||||||
|
private string _lastViewedFolderBeforeReload;
|
||||||
private SplitPanel _split;
|
private SplitPanel _split;
|
||||||
private Panel _contentViewPanel;
|
private Panel _contentViewPanel;
|
||||||
private Panel _contentTreePanel;
|
private Panel _contentTreePanel;
|
||||||
@@ -144,26 +145,6 @@ namespace FlaxEditor.Windows
|
|||||||
|
|
||||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||||
|
|
||||||
// Content database events
|
|
||||||
editor.ContentDatabase.WorkspaceModified += () => _isWorkspaceDirty = true;
|
|
||||||
editor.ContentDatabase.ItemRemoved += OnContentDatabaseItemRemoved;
|
|
||||||
editor.ContentDatabase.WorkspaceRebuilding += () => { _workspaceRebuildLocation = SelectedNode?.Path; };
|
|
||||||
editor.ContentDatabase.WorkspaceRebuilt += () =>
|
|
||||||
{
|
|
||||||
var selected = Editor.ContentDatabase.Find(_workspaceRebuildLocation);
|
|
||||||
if (selected is ContentFolder selectedFolder)
|
|
||||||
{
|
|
||||||
_navigationUnlocked = false;
|
|
||||||
RefreshView(selectedFolder.Node);
|
|
||||||
_tree.Select(selectedFolder.Node);
|
|
||||||
UpdateItemsSearch();
|
|
||||||
_navigationUnlocked = true;
|
|
||||||
UpdateUI();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ShowRoot();
|
|
||||||
};
|
|
||||||
|
|
||||||
var options = Editor.Options;
|
var options = Editor.Options;
|
||||||
options.OptionsChanged += OnOptionsChanged;
|
options.OptionsChanged += OnOptionsChanged;
|
||||||
|
|
||||||
@@ -1036,6 +1017,61 @@ namespace FlaxEditor.Windows
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnInit()
|
public override void OnInit()
|
||||||
|
{
|
||||||
|
// Content database events
|
||||||
|
Editor.ContentDatabase.WorkspaceModified += () => _isWorkspaceDirty = true;
|
||||||
|
Editor.ContentDatabase.ItemRemoved += OnContentDatabaseItemRemoved;
|
||||||
|
Editor.ContentDatabase.WorkspaceRebuilding += () => { _workspaceRebuildLocation = SelectedNode?.Path; };
|
||||||
|
Editor.ContentDatabase.WorkspaceRebuilt += () =>
|
||||||
|
{
|
||||||
|
var selected = Editor.ContentDatabase.Find(_workspaceRebuildLocation);
|
||||||
|
if (selected is ContentFolder selectedFolder)
|
||||||
|
{
|
||||||
|
_navigationUnlocked = false;
|
||||||
|
RefreshView(selectedFolder.Node);
|
||||||
|
_tree.Select(selectedFolder.Node);
|
||||||
|
UpdateItemsSearch();
|
||||||
|
_navigationUnlocked = true;
|
||||||
|
UpdateUI();
|
||||||
|
}
|
||||||
|
else if (_root != null)
|
||||||
|
ShowRoot();
|
||||||
|
};
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
// Load last viewed folder
|
||||||
|
if (Editor.ProjectCache.TryGetCustomData(ProjectDataLastViewedFolder, out string lastViewedFolder))
|
||||||
|
{
|
||||||
|
if (Editor.ContentDatabase.Find(lastViewedFolder) is ContentFolder folder)
|
||||||
|
_tree.Select(folder.Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||||
|
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScriptsReloadBegin()
|
||||||
|
{
|
||||||
|
var lastViewedFolder = _tree.Selection.Count == 1 ? _tree.SelectedNode as ContentTreeNode : null;
|
||||||
|
_lastViewedFolderBeforeReload = lastViewedFolder?.Path ?? string.Empty;
|
||||||
|
|
||||||
|
_tree.RemoveChild(_root);
|
||||||
|
_root = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnScriptsReloadEnd()
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(_lastViewedFolderBeforeReload))
|
||||||
|
{
|
||||||
|
if (Editor.ContentDatabase.Find(_lastViewedFolderBeforeReload) is ContentFolder folder)
|
||||||
|
_tree.Select(folder.Node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Refresh()
|
||||||
{
|
{
|
||||||
// Setup content root node
|
// Setup content root node
|
||||||
_root = new RootContentTreeNode
|
_root = new RootContentTreeNode
|
||||||
@@ -1072,13 +1108,6 @@ namespace FlaxEditor.Windows
|
|||||||
// Update UI layout
|
// Update UI layout
|
||||||
_isLayoutLocked = false;
|
_isLayoutLocked = false;
|
||||||
PerformLayout();
|
PerformLayout();
|
||||||
|
|
||||||
// Load last viewed folder
|
|
||||||
if (Editor.ProjectCache.TryGetCustomData(ProjectDataLastViewedFolder, out string lastViewedFolder))
|
|
||||||
{
|
|
||||||
if (Editor.ContentDatabase.Find(lastViewedFolder) is ContentFolder folder)
|
|
||||||
_tree.Select(folder.Node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -1226,6 +1255,8 @@ namespace FlaxEditor.Windows
|
|||||||
_viewDropdown = null;
|
_viewDropdown = null;
|
||||||
|
|
||||||
Editor.Options.OptionsChanged -= OnOptionsChanged;
|
Editor.Options.OptionsChanged -= OnOptionsChanged;
|
||||||
|
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||||
|
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||||
|
|
||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,15 +95,15 @@ namespace FlaxEditor.Windows
|
|||||||
{
|
{
|
||||||
case LogType.Warning:
|
case LogType.Warning:
|
||||||
Group = LogGroup.Warning;
|
Group = LogGroup.Warning;
|
||||||
Icon = _window.IconWarning;
|
Icon = _window._iconWarning;
|
||||||
break;
|
break;
|
||||||
case LogType.Info:
|
case LogType.Info:
|
||||||
Group = LogGroup.Info;
|
Group = LogGroup.Info;
|
||||||
Icon = _window.IconInfo;
|
Icon = _window._iconInfo;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Group = LogGroup.Error;
|
Group = LogGroup.Error;
|
||||||
Icon = _window.IconError;
|
Icon = _window._iconError;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,20 +131,21 @@ namespace FlaxEditor.Windows
|
|||||||
else if (index % 2 == 0)
|
else if (index % 2 == 0)
|
||||||
Render2D.FillRectangle(clientRect, style.Background * 0.9f);
|
Render2D.FillRectangle(clientRect, style.Background * 0.9f);
|
||||||
|
|
||||||
|
var color = Group == LogGroup.Error ? _window._colorError : (Group == LogGroup.Warning ? _window._colorWarning : _window._colorInfo);
|
||||||
|
|
||||||
// Icon
|
// Icon
|
||||||
var iconColor = Group == LogGroup.Error ? Color.Red : (Group == LogGroup.Warning ? Color.Yellow : style.Foreground);
|
Render2D.DrawSprite(Icon, new Rectangle(5, 0, 32, 32), color);
|
||||||
Render2D.DrawSprite(Icon, new Rectangle(5, 0, 32, 32), iconColor);
|
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
var textRect = new Rectangle(38, 2, clientRect.Width - 40, clientRect.Height - 10);
|
var textRect = new Rectangle(38, 2, clientRect.Width - 40, clientRect.Height - 10);
|
||||||
Render2D.PushClip(ref clientRect);
|
Render2D.PushClip(ref clientRect);
|
||||||
if (LogCount == 1)
|
if (LogCount == 1)
|
||||||
{
|
{
|
||||||
Render2D.DrawText(style.FontMedium, Desc.Title, textRect, style.Foreground);
|
Render2D.DrawText(style.FontMedium, Desc.Title, textRect, color);
|
||||||
}
|
}
|
||||||
else if (LogCount > 1)
|
else if (LogCount > 1)
|
||||||
{
|
{
|
||||||
Render2D.DrawText(style.FontMedium, $"{Desc.Title} ({LogCount})", textRect, style.Foreground);
|
Render2D.DrawText(style.FontMedium, $"{Desc.Title} ({LogCount})", textRect, color);
|
||||||
}
|
}
|
||||||
Render2D.PopClip();
|
Render2D.PopClip();
|
||||||
}
|
}
|
||||||
@@ -304,10 +305,12 @@ namespace FlaxEditor.Windows
|
|||||||
private readonly ToolStripButton[] _groupButtons = new ToolStripButton[3];
|
private readonly ToolStripButton[] _groupButtons = new ToolStripButton[3];
|
||||||
|
|
||||||
private LogType _iconType = LogType.Info;
|
private LogType _iconType = LogType.Info;
|
||||||
|
private SpriteHandle _iconInfo;
|
||||||
internal SpriteHandle IconInfo;
|
private SpriteHandle _iconWarning;
|
||||||
internal SpriteHandle IconWarning;
|
private SpriteHandle _iconError;
|
||||||
internal SpriteHandle IconError;
|
private Color _colorInfo;
|
||||||
|
private Color _colorWarning;
|
||||||
|
private Color _colorError;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="DebugLogWindow"/> class.
|
/// Initializes a new instance of the <see cref="DebugLogWindow"/> class.
|
||||||
@@ -317,7 +320,7 @@ namespace FlaxEditor.Windows
|
|||||||
: base(editor, true, ScrollBars.None)
|
: base(editor, true, ScrollBars.None)
|
||||||
{
|
{
|
||||||
Title = "Debug Log";
|
Title = "Debug Log";
|
||||||
Icon = IconInfo;
|
Icon = _iconInfo;
|
||||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||||
|
|
||||||
// Toolstrip
|
// Toolstrip
|
||||||
@@ -361,7 +364,6 @@ namespace FlaxEditor.Windows
|
|||||||
editor.Options.Apply(editor.Options.Options);
|
editor.Options.Apply(editor.Options.Options);
|
||||||
}).SetAutoCheck(true).LinkTooltip("Shows/hides info messages");
|
}).SetAutoCheck(true).LinkTooltip("Shows/hides info messages");
|
||||||
UpdateCount();
|
UpdateCount();
|
||||||
OnEditorOptionsChanged(Editor.Options.Options);
|
|
||||||
|
|
||||||
// Split panel
|
// Split panel
|
||||||
_split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both)
|
_split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both)
|
||||||
@@ -394,14 +396,17 @@ namespace FlaxEditor.Windows
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Cache entries icons
|
// Cache entries icons
|
||||||
IconInfo = Editor.Icons.Info64;
|
_iconInfo = Editor.Icons.Info64;
|
||||||
IconWarning = Editor.Icons.Warning64;
|
_iconWarning = Editor.Icons.Warning64;
|
||||||
IconError = Editor.Icons.Error64;
|
_iconError = Editor.Icons.Error64;
|
||||||
|
|
||||||
// Bind events
|
// Bind events
|
||||||
Editor.Options.OptionsChanged += OnEditorOptionsChanged;
|
Editor.Options.OptionsChanged += OnEditorOptionsChanged;
|
||||||
Debug.Logger.LogHandler.SendLog += LogHandlerOnSendLog;
|
Debug.Logger.LogHandler.SendLog += LogHandlerOnSendLog;
|
||||||
Debug.Logger.LogHandler.SendExceptionLog += LogHandlerOnSendExceptionLog;
|
Debug.Logger.LogHandler.SendExceptionLog += LogHandlerOnSendExceptionLog;
|
||||||
|
|
||||||
|
// Init editor options
|
||||||
|
OnEditorOptionsChanged(Editor.Options.Options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEditorOptionsChanged(EditorOptions options)
|
private void OnEditorOptionsChanged(EditorOptions options)
|
||||||
@@ -413,6 +418,9 @@ namespace FlaxEditor.Windows
|
|||||||
_groupButtons[0].Checked = options.Interface.DebugLogShowErrorMessages;
|
_groupButtons[0].Checked = options.Interface.DebugLogShowErrorMessages;
|
||||||
_groupButtons[1].Checked = options.Interface.DebugLogShowWarningMessages;
|
_groupButtons[1].Checked = options.Interface.DebugLogShowWarningMessages;
|
||||||
_groupButtons[2].Checked = options.Interface.DebugLogShowInfoMessages;
|
_groupButtons[2].Checked = options.Interface.DebugLogShowInfoMessages;
|
||||||
|
_colorInfo = options.Interface.OutputLogTextColor;
|
||||||
|
_colorWarning = options.Interface.OutputLogWarningTextColor;
|
||||||
|
_colorError = options.Interface.OutputLogErrorTextColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -422,7 +430,6 @@ namespace FlaxEditor.Windows
|
|||||||
{
|
{
|
||||||
if (_entriesPanel == null)
|
if (_entriesPanel == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RemoveEntries();
|
RemoveEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ namespace FlaxEditor.Windows
|
|||||||
private readonly GameRoot _guiRoot;
|
private readonly GameRoot _guiRoot;
|
||||||
private bool _showGUI = true;
|
private bool _showGUI = true;
|
||||||
private bool _showDebugDraw = false;
|
private bool _showDebugDraw = false;
|
||||||
|
private bool _audioMuted = false;
|
||||||
|
private float _audioVolume = 1;
|
||||||
private bool _isMaximized = false, _isUnlockingMouse = false;
|
private bool _isMaximized = false, _isUnlockingMouse = false;
|
||||||
private bool _isFloating = false, _isBorderless = false;
|
private bool _isFloating = false, _isBorderless = false;
|
||||||
private bool _cursorVisible = true;
|
private bool _cursorVisible = true;
|
||||||
@@ -91,6 +93,35 @@ namespace FlaxEditor.Windows
|
|||||||
set => _showDebugDraw = value;
|
set => _showDebugDraw = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or set a value indicating whether Audio is muted.
|
||||||
|
/// </summary>
|
||||||
|
public bool AudioMuted
|
||||||
|
{
|
||||||
|
get => _audioMuted;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Audio.MasterVolume = value ? 0 : AudioVolume;
|
||||||
|
_audioMuted = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value that set the audio volume.
|
||||||
|
/// </summary>
|
||||||
|
public float AudioVolume
|
||||||
|
{
|
||||||
|
get => _audioVolume;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!AudioMuted)
|
||||||
|
Audio.MasterVolume = value;
|
||||||
|
|
||||||
|
_audioVolume = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the game window is maximized (only in play mode).
|
/// Gets or sets a value indicating whether the game window is maximized (only in play mode).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -646,6 +677,24 @@ namespace FlaxEditor.Windows
|
|||||||
checkbox.StateChanged += x => ShowDebugDraw = x.Checked;
|
checkbox.StateChanged += x => ShowDebugDraw = x.Checked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
menu.AddSeparator();
|
||||||
|
|
||||||
|
// Mute Audio
|
||||||
|
{
|
||||||
|
var button = menu.AddButton("Mute Audio");
|
||||||
|
button.CloseMenuOnClick = false;
|
||||||
|
var checkbox = new CheckBox(140, 2, AudioMuted) { Parent = button };
|
||||||
|
checkbox.StateChanged += x => AudioMuted = x.Checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio Volume
|
||||||
|
{
|
||||||
|
var button = menu.AddButton("Audio Volume");
|
||||||
|
button.CloseMenuOnClick = false;
|
||||||
|
var slider = new FloatValueBox(AudioVolume, 140, 2, 50, 0, 1) { Parent = button };
|
||||||
|
slider.ValueChanged += () => AudioVolume = slider.Value;
|
||||||
|
}
|
||||||
|
|
||||||
menu.MinimumWidth = 200;
|
menu.MinimumWidth = 200;
|
||||||
menu.AddSeparator();
|
menu.AddSeparator();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -286,7 +286,9 @@ namespace FlaxEditor.Windows
|
|||||||
_output.DefaultStyle.Font == options.Interface.OutputLogTextFont &&
|
_output.DefaultStyle.Font == options.Interface.OutputLogTextFont &&
|
||||||
_output.DefaultStyle.Color == options.Interface.OutputLogTextColor &&
|
_output.DefaultStyle.Color == options.Interface.OutputLogTextColor &&
|
||||||
_output.DefaultStyle.ShadowColor == options.Interface.OutputLogTextShadowColor &&
|
_output.DefaultStyle.ShadowColor == options.Interface.OutputLogTextShadowColor &&
|
||||||
_output.DefaultStyle.ShadowOffset == options.Interface.OutputLogTextShadowOffset)
|
_output.DefaultStyle.ShadowOffset == options.Interface.OutputLogTextShadowOffset &&
|
||||||
|
_output.WarningStyle.Color == options.Interface.OutputLogWarningTextColor &&
|
||||||
|
_output.ErrorStyle.Color == options.Interface.OutputLogErrorTextColor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_output.DefaultStyle = new TextBlockStyle
|
_output.DefaultStyle = new TextBlockStyle
|
||||||
@@ -297,10 +299,11 @@ namespace FlaxEditor.Windows
|
|||||||
ShadowOffset = options.Interface.OutputLogTextShadowOffset,
|
ShadowOffset = options.Interface.OutputLogTextShadowOffset,
|
||||||
BackgroundSelectedBrush = new SolidColorBrush(Style.Current.BackgroundSelected),
|
BackgroundSelectedBrush = new SolidColorBrush(Style.Current.BackgroundSelected),
|
||||||
};
|
};
|
||||||
|
|
||||||
_output.WarningStyle = _output.DefaultStyle;
|
_output.WarningStyle = _output.DefaultStyle;
|
||||||
_output.WarningStyle.Color = Color.Yellow;
|
_output.WarningStyle.Color = options.Interface.OutputLogWarningTextColor;
|
||||||
_output.ErrorStyle = _output.DefaultStyle;
|
_output.ErrorStyle = _output.DefaultStyle;
|
||||||
_output.ErrorStyle.Color = Color.Red;
|
_output.ErrorStyle.Color = options.Interface.OutputLogErrorTextColor;
|
||||||
|
|
||||||
_timestampsFormats = options.Interface.OutputLogTimestampsFormat;
|
_timestampsFormats = options.Interface.OutputLogTimestampsFormat;
|
||||||
_showLogType = options.Interface.OutputLogShowLogType;
|
_showLogType = options.Interface.OutputLogShowLogType;
|
||||||
@@ -601,7 +604,7 @@ namespace FlaxEditor.Windows
|
|||||||
var cachedScrollValue = _vScroll.Value;
|
var cachedScrollValue = _vScroll.Value;
|
||||||
var cachedSelection = _output.SelectionRange;
|
var cachedSelection = _output.SelectionRange;
|
||||||
var cachedOutputTargetViewOffset = _output.TargetViewOffset;
|
var cachedOutputTargetViewOffset = _output.TargetViewOffset;
|
||||||
var isBottomScroll = _vScroll.Value >= _vScroll.Maximum - (_scrollSize*2) || wasEmpty;
|
var isBottomScroll = _vScroll.Value >= _vScroll.Maximum - (_scrollSize * 2) || wasEmpty;
|
||||||
_output.Text = _textBuffer.ToString();
|
_output.Text = _textBuffer.ToString();
|
||||||
_output.TargetViewOffset = cachedOutputTargetViewOffset;
|
_output.TargetViewOffset = cachedOutputTargetViewOffset;
|
||||||
_textBufferCount = _entries.Count;
|
_textBufferCount = _entries.Count;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user