Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3554747a67 | |||
| 62968dd437 | |||
| c660fac524 | |||
| 431a69e357 | |||
| f4fcc07288 | |||
| a38cc4d5cb | |||
| 1528d458d9 | |||
| 9e937776ac | |||
| a8aebdd01f | |||
| 998ed87029 | |||
| 279b3f8d9a | |||
| 738a506b6d | |||
| 0ddecdda1f | |||
| 94a22907e2 | |||
| d22a0aad0c | |||
| 9e035f3818 | |||
| 99a810458a | |||
| 2806578126 | |||
| 882e9a6623 | |||
| 14c156e351 | |||
| cd2151332e | |||
| 53bbca3779 | |||
| 51f4ac467e | |||
| 81427a7f9e | |||
| faadfb28b3 | |||
| 6bfe0bed35 | |||
| 6e4d5b853f | |||
| 0ebe23b482 | |||
| abbde5861a | |||
| b78d4349a7 | |||
| 3c1d3234b8 | |||
|
|
79baaae8e7 | ||
| 79289662ed | |||
| 89a2985ad8 | |||
| 1f0a521a87 | |||
| 8a0e43c38c | |||
| ac9022f585 | |||
| 314dbbbeaf | |||
| f13e09910d | |||
| 67b9511afe | |||
| 510c477468 | |||
| 697fcc18ab | |||
| 89ff08b3f2 | |||
| 9417585cd9 | |||
| f794bb5455 | |||
| bb7a5326cd | |||
| a998b2a44e | |||
| a69eb4296f | |||
| 727af5a5b9 | |||
| d545dd8219 | |||
| 29e385ab4b | |||
| 5c63e30b84 | |||
| 5187c677f1 | |||
| 1d43314efd | |||
| 91ef8c69db | |||
| f24251af82 | |||
| ed6e0138e6 | |||
| 4362cdb396 | |||
| 8146680b53 | |||
| 27aa2cfa1f |
6
.github/workflows/cd.yml
vendored
6
.github/workflows/cd.yml
vendored
@@ -1,13 +1,13 @@
|
||||
name: Continuous Deployment
|
||||
on:
|
||||
schedule:
|
||||
- cron: '15 6 * * *'
|
||||
- cron: '15 4 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
DOTNET_NOLOGO: true
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: false
|
||||
GIT_LFS_PULL_OPTIONS: '-c lfs.concurrenttransfers=1 -c lfs.transfer.maxretries=2 -c http.version="HTTP/1.1" -c lfs.activitytimeout=60'
|
||||
GIT_LFS_PULL_OPTIONS: '-c lfs.concurrenttransfers=10 -c lfs.transfer.maxretries=2'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
- name: Checkout LFS
|
||||
run: |
|
||||
git lfs version
|
||||
git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
||||
GIT_TRACE=1 GIT_TRANSFER_TRACE=1 git ${{ env.GIT_LFS_PULL_OPTIONS }} lfs pull
|
||||
- name: Install dependencies
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Redirect to our own Git LFS server
|
||||
[lfs]
|
||||
#url="https://gitlab.flaxengine.com/flax/flaxengine.git/info/lfs"
|
||||
locksverify = false
|
||||
locksverify = false
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Content/Shaders/Editor/Grid.flax
LFS
BIN
Content/Shaders/Editor/Grid.flax
LFS
Binary file not shown.
@@ -15,7 +15,7 @@ if errorlevel 1 goto BuildToolFailed
|
||||
|
||||
:: Build bindings for all editor configurations
|
||||
echo Building C# bindings...
|
||||
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor,FlaxGame
|
||||
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
||||
|
||||
popd
|
||||
echo Done!
|
||||
|
||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Mac/CallBuildTool.sh --genproject "$@"
|
||||
# Build bindings for all editor configurations
|
||||
echo Building C# bindings...
|
||||
# TODO: Detect the correct architecture here
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor,FlaxGame
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=ARM64 -platform=Mac --buildTargets=FlaxEditor
|
||||
|
||||
@@ -14,4 +14,4 @@ bash ./Development/Scripts/Linux/CallBuildTool.sh --genproject "$@"
|
||||
# Build bindings for all editor configurations
|
||||
echo Building C# bindings...
|
||||
# TODO: Detect the correct architecture here
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor,FlaxGame
|
||||
Binaries/Tools/Flax.Build -build -BuildBindingsOnly -arch=x64 -platform=Linux --buildTargets=FlaxEditor
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Content.Create;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.CustomEditors.Editors;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
@@ -86,67 +84,18 @@ namespace FlaxEditor.Content
|
||||
|
||||
if (_element != null)
|
||||
{
|
||||
_element.CustomControl.CheckValid += OnCheckValidJsonAssetType;
|
||||
// Define the rule for the types that can be used to create a json data asset
|
||||
_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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +175,7 @@ namespace FlaxEditor.Content
|
||||
{
|
||||
_thumbnail = SpriteHandle.Invalid;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with overriden thumbnail.
|
||||
/// </summary>
|
||||
@@ -247,7 +196,7 @@ namespace FlaxEditor.Content
|
||||
{
|
||||
Editor.SaveJsonAsset(outputPath, new T());
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override AssetItem ConstructItem(string path, string typeName, ref Guid id)
|
||||
{
|
||||
|
||||
@@ -496,7 +496,7 @@ namespace FlaxEditor.Content.Thumbnails
|
||||
// Prepare requests
|
||||
bool isAnyReady = false;
|
||||
int checks = Mathf.Min(10, _requests.Count);
|
||||
for (int i = 0; i < checks && i < _requests.Count; i++)
|
||||
for (int i = 0; i < checks; i++)
|
||||
{
|
||||
var request = _requests[i];
|
||||
try
|
||||
|
||||
@@ -1277,8 +1277,6 @@ bool CookAssetsStep::Perform(CookingData& data)
|
||||
assetStats.Count++;
|
||||
assetStats.ContentSize += FileSystem::GetFileSize(cookedFilePath);
|
||||
|
||||
LOG(Info, "Cooked size of {0}: {1}KB", assetId, (FileSystem::GetFileSize(cookedFilePath) / (1024)));
|
||||
|
||||
if (packageBuilder.Add(data, i->Value, cookedFilePath))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -415,9 +415,9 @@ bool DeployDataStep::Perform(CookingData& data)
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/NormalTexture"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/BlackTexture"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/WhiteTexture"));
|
||||
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensStarburst"));
|
||||
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensColor"));
|
||||
//data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensDirt"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensStarburst"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensColor"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/DefaultLensDirt"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Circle"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Hexagon"));
|
||||
data.AddRootEngineAsset(TEXT("Engine/Textures/Bokeh/Octagon"));
|
||||
|
||||
@@ -195,15 +195,6 @@ namespace FlaxEditor.CustomEditors
|
||||
Presenter.AfterLayout?.Invoke(layout);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
Editor = null;
|
||||
_overrideEditor = null;
|
||||
|
||||
base.Deinitialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnModified()
|
||||
{
|
||||
|
||||
@@ -68,16 +68,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
// Use default prefab instance as a reference for the editor
|
||||
Values.SetReferenceValue(prefabInstance);
|
||||
|
||||
// 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)
|
||||
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
|
||||
{
|
||||
var targetPrefab = nestedPrefab ?? prefab;
|
||||
// Add some UI
|
||||
var panel = layout.CustomContainer<UniformGridPanel>();
|
||||
panel.CustomControl.Height = 20.0f;
|
||||
panel.CustomControl.SlotsVertically = 1;
|
||||
panel.CustomControl.SlotsHorizontally = 3;
|
||||
|
||||
// Selecting actor prefab asset
|
||||
@@ -85,21 +81,17 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
selectPrefab.Button.Clicked += () =>
|
||||
{
|
||||
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
|
||||
Editor.Instance.Windows.ContentWin.Select(targetPrefab);
|
||||
Editor.Instance.Windows.ContentWin.Select(prefab);
|
||||
};
|
||||
|
||||
// Edit selected prefab asset
|
||||
var editPrefab = panel.Button("Edit Prefab");
|
||||
editPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(targetPrefab.ID));
|
||||
}
|
||||
else
|
||||
{
|
||||
panel.CustomControl.SlotsHorizontally = 1;
|
||||
}
|
||||
editPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(prefab.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));
|
||||
// Viewing changes applied to this actor
|
||||
var viewChanges = panel.Button("View Changes");
|
||||
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
|
||||
}
|
||||
|
||||
// Link event to update editor on prefab apply
|
||||
_linkedPrefabId = prefab.ID;
|
||||
@@ -206,7 +198,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
if (_linkedPrefabId != Guid.Empty)
|
||||
{
|
||||
_linkedPrefabId = Guid.Empty;
|
||||
Editor.Instance.Prefabs.PrefabApplying -= OnPrefabApplying;
|
||||
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplying;
|
||||
Editor.Instance.Prefabs.PrefabApplied -= OnPrefabApplied;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,23 +15,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
private int _firstTimeShow;
|
||||
private BezierCurveEditor<T> _curve;
|
||||
private Splitter _splitter;
|
||||
private string _heightCachedPath;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var item = layout.CustomContainer<BezierCurveEditor<T>>();
|
||||
_curve = item.CustomControl;
|
||||
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.Height = 120.0f;
|
||||
_curve.Edited += OnCurveEdited;
|
||||
_firstTimeShow = 4; // For some weird reason it needs several frames of warmup (probably due to sliders smoothing)
|
||||
_splitter = new Splitter
|
||||
@@ -55,11 +45,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
|
||||
private void OnSplitterMoved(Float2 location)
|
||||
{
|
||||
_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);
|
||||
_curve.Height = Mathf.Clamp(_splitter.PointToParent(location).Y, 50.0f, 1000.0f);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -147,23 +133,13 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
private int _firstTimeShow;
|
||||
private LinearCurveEditor<T> _curve;
|
||||
private Splitter _splitter;
|
||||
private string _heightCachedPath;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
var item = layout.CustomContainer<LinearCurveEditor<T>>();
|
||||
_curve = item.CustomControl;
|
||||
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.Height = 120.0f;
|
||||
_curve.Edited += OnCurveEdited;
|
||||
_firstTimeShow = 4; // For some weird reason it needs several frames of warmup (probably due to sliders smoothing)
|
||||
_splitter = new Splitter
|
||||
@@ -188,10 +164,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
private void OnSplitterMoved(Float2 location)
|
||||
{
|
||||
_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 />
|
||||
|
||||
@@ -1057,7 +1057,6 @@ namespace FlaxEditor.CustomEditors.Dedicated
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
_scriptToggles = null;
|
||||
_scripts.Clear();
|
||||
|
||||
base.Deinitialize();
|
||||
}
|
||||
|
||||
@@ -123,9 +123,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
base.Refresh();
|
||||
|
||||
var differentValues = HasDifferentValues;
|
||||
Picker.DifferentValues = differentValues;
|
||||
if (!differentValues)
|
||||
if (!HasDifferentValues)
|
||||
{
|
||||
_isRefreshing = true;
|
||||
var value = Values[0];
|
||||
@@ -377,9 +375,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
base.Refresh();
|
||||
|
||||
_isRefreshing = true;
|
||||
_textBox.Text = HasDifferentValues ? "Multiple Values" : GetPath();
|
||||
_isRefreshing = false;
|
||||
if (!HasDifferentValues)
|
||||
{
|
||||
_isRefreshing = true;
|
||||
_textBox.Text = GetPath();
|
||||
_isRefreshing = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
public override void Initialize(LayoutElementsContainer layout)
|
||||
{
|
||||
_label = layout.ClickableLabel(Path).CustomControl;
|
||||
_label.Margin = new Margin(0, 20.0f, 0, 0);
|
||||
_label.ClipText = true;
|
||||
_label.RightClick += ShowPicker;
|
||||
var button = new Button
|
||||
{
|
||||
|
||||
@@ -9,8 +9,6 @@ using FlaxEditor.GUI.Drag;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEditor.SceneGraph.GUI;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Utilities;
|
||||
@@ -42,11 +40,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
private DragScripts _dragScripts;
|
||||
private DragHandlers _dragHandlers;
|
||||
|
||||
/// <summary>
|
||||
/// The presenter using this control.
|
||||
/// </summary>
|
||||
public IPresenterOwner PresenterContext;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the allowed objects type (given type and all sub classes). Must be <see cref="Object"/> type of any subclass.
|
||||
/// </summary>
|
||||
@@ -136,11 +129,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// </summary>
|
||||
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>
|
||||
/// Initializes a new instance of the <see cref="FlaxObjectRefPickerControl"/> class.
|
||||
/// </summary>
|
||||
@@ -166,7 +154,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Value = actor;
|
||||
RootWindow.Focus();
|
||||
Focus();
|
||||
}, PresenterContext);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -175,7 +163,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Value = script;
|
||||
RootWindow.Focus();
|
||||
Focus();
|
||||
}, PresenterContext);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,14 +197,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
Render2D.DrawRectangle(frameRect, isEnabled && (IsMouseOver || IsNavFocused) ? style.BorderHighlighted : style.BorderNormal);
|
||||
|
||||
// Check if has item selected
|
||||
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)
|
||||
if (isSelected)
|
||||
{
|
||||
// Draw name
|
||||
Render2D.PushClip(nameRect);
|
||||
@@ -345,19 +326,10 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PresenterContext is PropertiesWindow)
|
||||
_linkedTreeNode = Editor.Instance.Scene.GetActorNode(actor).TreeNode;
|
||||
else if (PresenterContext is PrefabWindow prefabWindow)
|
||||
_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();
|
||||
}
|
||||
_linkedTreeNode = Editor.Instance.Scene.GetActorNode(actor).TreeNode;
|
||||
_linkedTreeNode.ExpandAllParents();
|
||||
Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true);
|
||||
_linkedTreeNode.StartHighlight();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -400,20 +372,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
// Select object
|
||||
if (_value is Actor actor)
|
||||
{
|
||||
if (PresenterContext is PropertiesWindow)
|
||||
Editor.Instance.SceneEditing.Select(actor);
|
||||
else if (PresenterContext is PrefabWindow prefabWindow)
|
||||
prefabWindow.Select(prefabWindow.Graph.Root.Find(actor));
|
||||
}
|
||||
Editor.Instance.SceneEditing.Select(actor);
|
||||
else if (_value is Script script && 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));
|
||||
}
|
||||
Editor.Instance.SceneEditing.Select(script.Actor);
|
||||
else if (_value is Asset asset)
|
||||
Editor.Instance.Windows.ContentWin.Select(asset);
|
||||
}
|
||||
@@ -454,13 +415,13 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
// Ensure to have valid drag helpers (uses lazy init)
|
||||
if (_dragActors == null)
|
||||
_dragActors = new DragActors(ValidateDragActor);
|
||||
_dragActors = new DragActors(x => IsValid(x.Actor));
|
||||
if (_dragActorsWithScript == null)
|
||||
_dragActorsWithScript = new DragActors(ValidateDragActorWithScript);
|
||||
if (_dragAssets == null)
|
||||
_dragAssets = new DragAssets(ValidateDragAsset);
|
||||
if (_dragScripts == null)
|
||||
_dragScripts = new DragScripts(ValidateDragScript);
|
||||
_dragScripts = new DragScripts(IsValid);
|
||||
if (_dragHandlers == null)
|
||||
{
|
||||
_dragHandlers = new DragHandlers
|
||||
@@ -485,43 +446,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
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)
|
||||
{
|
||||
// Check if can accept assets
|
||||
@@ -540,18 +464,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
|
||||
private bool ValidateDragActorWithScript(ActorNode node)
|
||||
{
|
||||
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;
|
||||
return node.Actor.Scripts.Any(IsValid);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -623,7 +536,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (!HasDifferentTypes)
|
||||
{
|
||||
_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.ValueChanged += () => SetValue(_element.CustomControl.Value);
|
||||
}
|
||||
@@ -634,9 +546,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
{
|
||||
base.Refresh();
|
||||
|
||||
var differentValues = HasDifferentValues;
|
||||
_element.CustomControl.DifferentValues = differentValues;
|
||||
if (!differentValues)
|
||||
if (!HasDifferentValues)
|
||||
{
|
||||
_element.CustomControl.Value = Values[0] as Object;
|
||||
}
|
||||
|
||||
@@ -819,15 +819,6 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
OnGroupsEnd();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Deinitialize()
|
||||
{
|
||||
_visibleIfCaches = null;
|
||||
_visibleIfPropertiesListsCache = null;
|
||||
|
||||
base.Deinitialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Refresh()
|
||||
{
|
||||
|
||||
@@ -96,20 +96,6 @@ namespace FlaxEditor.CustomEditors
|
||||
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>
|
||||
/// Adds new group element.
|
||||
/// </summary>
|
||||
@@ -126,7 +112,14 @@ namespace FlaxEditor.CustomEditors
|
||||
if (presenter != null && (presenter.Features & FeatureFlags.CacheExpandedGroups) != 0)
|
||||
{
|
||||
// Build group identifier (made of path from group titles)
|
||||
var expandPath = GetLayoutCachePath(title);
|
||||
var expandPath = 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)
|
||||
if (Editor.Instance.ProjectCache.IsGroupToggled(expandPath) ^ isSubGroup)
|
||||
|
||||
@@ -250,7 +250,7 @@ namespace FlaxEditor.CustomEditors
|
||||
if (objA == null && objB is string objBStr && objBStr.Length == 0)
|
||||
return true;
|
||||
|
||||
return FlaxEngine.Json.JsonSerializer.ValueEquals(objA, objB);
|
||||
return Newtonsoft.Json.Utilities.MiscellaneousUtils.ValueEquals(objA, objB);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1686,6 +1686,9 @@ namespace FlaxEditor
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
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))]
|
||||
internal static partial float Internal_GetAnimationTime(IntPtr animatedModel);
|
||||
|
||||
|
||||
@@ -48,11 +48,6 @@ namespace FlaxEditor.GUI
|
||||
/// </summary>
|
||||
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>
|
||||
/// Initializes a new instance of the <see cref="AssetPicker"/> class.
|
||||
/// </summary>
|
||||
@@ -126,13 +121,7 @@ namespace FlaxEditor.GUI
|
||||
if (CanEdit)
|
||||
Render2D.DrawSprite(style.ArrowDown, button1Rect, button1Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
||||
|
||||
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)
|
||||
if (Validator.SelectedItem != null)
|
||||
{
|
||||
// Draw item preview
|
||||
Validator.SelectedItem.DrawThumbnail(ref iconRect);
|
||||
|
||||
@@ -30,10 +30,8 @@ namespace FlaxEditor.GUI
|
||||
internal bool _isMovingTangent;
|
||||
internal bool _movedView;
|
||||
internal bool _movedKeyframes;
|
||||
internal bool _toggledSelection;
|
||||
private TangentPoint _movingTangent;
|
||||
private Float2 _movingSelectionStart;
|
||||
private Float2 _movingSelectionStartPosLock;
|
||||
private Float2[] _movingSelectionOffsets;
|
||||
private Float2 _cmShowPos;
|
||||
|
||||
@@ -58,11 +56,12 @@ namespace FlaxEditor.GUI
|
||||
internal void UpdateSelection(ref Rectangle selectionRect)
|
||||
{
|
||||
// Find controls to select
|
||||
var children = _children;
|
||||
for (int i = 0; i < children.Count; i++)
|
||||
for (int i = 0; i < Children.Count; i++)
|
||||
{
|
||||
if (children[i] is KeyframePoint p)
|
||||
if (Children[i] is KeyframePoint p)
|
||||
{
|
||||
p.IsSelected = p.Bounds.Intersects(ref selectionRect);
|
||||
}
|
||||
}
|
||||
_editor.UpdateTangents();
|
||||
}
|
||||
@@ -73,7 +72,6 @@ namespace FlaxEditor.GUI
|
||||
_isMovingSelection = true;
|
||||
_movedKeyframes = false;
|
||||
var viewRect = _editor._mainPanel.GetClientArea();
|
||||
_movingSelectionStartPosLock = location;
|
||||
_movingSelectionStart = PointToKeyframes(location, ref viewRect);
|
||||
if (_movingSelectionOffsets == null || _movingSelectionOffsets.Length != _editor._points.Count)
|
||||
_movingSelectionOffsets = new Float2[_editor._points.Count];
|
||||
@@ -84,17 +82,10 @@ namespace FlaxEditor.GUI
|
||||
|
||||
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 locationKeyframes = PointToKeyframes(location, ref viewRect);
|
||||
var accessor = _editor.Accessor;
|
||||
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++)
|
||||
{
|
||||
var p = _editor._points[i];
|
||||
@@ -131,20 +122,7 @@ namespace FlaxEditor.GUI
|
||||
if (isFirstSelected)
|
||||
{
|
||||
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)
|
||||
{
|
||||
float fps = _editor.FPS.Value;
|
||||
@@ -153,6 +131,8 @@ namespace FlaxEditor.GUI
|
||||
time = Mathf.Clamp(time, minTime, maxTime);
|
||||
}
|
||||
|
||||
// TODO: snapping keyframes to grid when moving
|
||||
|
||||
_editor.SetKeyframeInternal(p.Index, time, value, p.Component);
|
||||
}
|
||||
_editor.UpdateKeyframes();
|
||||
@@ -254,11 +234,7 @@ namespace FlaxEditor.GUI
|
||||
var k = _editor.GetKeyframe(_movingTangent.Index);
|
||||
var kv = _editor.GetKeyframeValue(k);
|
||||
var value = _editor.Accessor.GetCurveValue(ref kv, _movingTangent.Component);
|
||||
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;
|
||||
_movingTangent.TangentValue = PointToKeyframes(location, ref viewRect).Y - value;
|
||||
_editor.UpdateTangents();
|
||||
Cursor = CursorType.SizeNS;
|
||||
_movedKeyframes = true;
|
||||
@@ -307,7 +283,6 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
|
||||
// Cache data
|
||||
_toggledSelection = false;
|
||||
_isMovingSelection = false;
|
||||
_isMovingTangent = false;
|
||||
_mousePos = location;
|
||||
@@ -330,7 +305,13 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
if (_leftMouseDown)
|
||||
{
|
||||
if (Root.GetKey(KeyboardKeys.Shift))
|
||||
if (Root.GetKey(KeyboardKeys.Control))
|
||||
{
|
||||
// Toggle selection
|
||||
keyframe.IsSelected = !keyframe.IsSelected;
|
||||
_editor.UpdateTangents();
|
||||
}
|
||||
else if (Root.GetKey(KeyboardKeys.Shift))
|
||||
{
|
||||
// Select range
|
||||
keyframe.IsSelected = true;
|
||||
@@ -354,14 +335,10 @@ namespace FlaxEditor.GUI
|
||||
else if (!keyframe.IsSelected)
|
||||
{
|
||||
// Select node
|
||||
if (!Root.GetKey(KeyboardKeys.Control))
|
||||
{
|
||||
if (_editor.KeyframesEditorContext != null)
|
||||
_editor.KeyframesEditorContext.OnKeyframesDeselect(_editor);
|
||||
else
|
||||
_editor.ClearSelection();
|
||||
}
|
||||
_toggledSelection = true;
|
||||
if (_editor.KeyframesEditorContext != null)
|
||||
_editor.KeyframesEditorContext.OnKeyframesDeselect(_editor);
|
||||
else
|
||||
_editor.ClearSelection();
|
||||
keyframe.IsSelected = true;
|
||||
_editor.UpdateTangents();
|
||||
}
|
||||
@@ -452,12 +429,6 @@ namespace FlaxEditor.GUI
|
||||
else
|
||||
OnMoveEnd(location);
|
||||
}
|
||||
// Toggle selection
|
||||
else if (!_toggledSelection && Root.GetKey(KeyboardKeys.Control) && GetChildAt(location) is KeyframePoint keyframe)
|
||||
{
|
||||
keyframe.IsSelected = !keyframe.IsSelected;
|
||||
_editor.UpdateTangents();
|
||||
}
|
||||
|
||||
_isMovingSelection = false;
|
||||
_isMovingTangent = false;
|
||||
@@ -543,11 +514,11 @@ namespace FlaxEditor.GUI
|
||||
{
|
||||
if (base.OnMouseDoubleClick(location, button))
|
||||
return true;
|
||||
|
||||
|
||||
// Add keyframe on double click
|
||||
var child = GetChildAt(location);
|
||||
if (child is not KeyframePoint &&
|
||||
child is not TangentPoint &&
|
||||
if (child is not KeyframePoint &&
|
||||
child is not TangentPoint &&
|
||||
_editor.KeyframesCount < _editor.MaxKeyframes)
|
||||
{
|
||||
var viewRect = _editor._mainPanel.GetClientArea();
|
||||
@@ -574,7 +545,7 @@ namespace FlaxEditor.GUI
|
||||
var viewRect = _editor._mainPanel.GetClientArea();
|
||||
var locationInKeyframes = PointToKeyframes(location, ref viewRect);
|
||||
var locationInEditorBefore = _editor.PointFromKeyframes(locationInKeyframes, ref viewRect);
|
||||
|
||||
|
||||
// Scale relative to the curve size
|
||||
var scale = new Float2(delta * 0.1f);
|
||||
_editor._mainPanel.GetDesireClientArea(out var mainPanelArea);
|
||||
|
||||
@@ -163,11 +163,10 @@ namespace FlaxEditor.GUI
|
||||
/// <inheritdoc />
|
||||
public override void Draw()
|
||||
{
|
||||
var style = Style.Current;
|
||||
var rect = new Rectangle(Float2.Zero, Size);
|
||||
var color = Editor.ShowCollapsed ? style.ForegroundDisabled : Editor.Colors[Component];
|
||||
var color = Editor.ShowCollapsed ? Color.Gray : Editor.Colors[Component];
|
||||
if (IsSelected)
|
||||
color = Editor.ContainsFocus ? style.SelectionBorder : Color.Lerp(style.ForegroundDisabled, style.SelectionBorder, 0.4f);
|
||||
color = Editor.ContainsFocus ? Color.YellowGreen : Color.Lerp(Color.Gray, Color.YellowGreen, 0.4f);
|
||||
if (IsMouseOver)
|
||||
color *= 1.1f;
|
||||
Render2D.FillRectangle(rect, color);
|
||||
@@ -245,19 +244,14 @@ namespace FlaxEditor.GUI
|
||||
set => Editor.SetKeyframeTangentInternal(Index, IsIn, Component, value);
|
||||
}
|
||||
|
||||
internal float TangentOffset => 50.0f / Editor.ViewScale.X;
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
Render2D.DrawLine(size * 0.5f, pointPos, style.ForegroundDisabled, thickness);
|
||||
Render2D.DrawLine(Size * 0.5f, pointPos, Color.Gray);
|
||||
|
||||
var rect = new Rectangle(Float2.Zero, size);
|
||||
var color = style.BorderSelected;
|
||||
var rect = new Rectangle(Float2.Zero, Size);
|
||||
var color = Color.MediumVioletRed;
|
||||
if (IsMouseOver)
|
||||
color *= 1.1f;
|
||||
Render2D.FillRectangle(rect, color);
|
||||
@@ -295,7 +289,7 @@ namespace FlaxEditor.GUI
|
||||
/// <summary>
|
||||
/// The curve time/value axes tick steps.
|
||||
/// </summary>
|
||||
protected double[] TickSteps = Utilities.Utils.CurveTickSteps;
|
||||
protected float[] TickSteps = Utilities.Utils.CurveTickSteps;
|
||||
|
||||
/// <summary>
|
||||
/// The curve contents area.
|
||||
@@ -448,7 +442,7 @@ namespace FlaxEditor.GUI
|
||||
_mainPanel = new Panel(ScrollBars.Both)
|
||||
{
|
||||
ScrollMargin = new Margin(150.0f),
|
||||
AlwaysShowScrollbars = false,
|
||||
AlwaysShowScrollbars = true,
|
||||
AnchorPreset = AnchorPresets.StretchAll,
|
||||
Offsets = Margin.Zero,
|
||||
Parent = this
|
||||
@@ -674,82 +668,26 @@ namespace FlaxEditor.GUI
|
||||
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 />
|
||||
public override void ShowWholeCurve()
|
||||
{
|
||||
ShowCurve(false);
|
||||
_mainPanel.GetDesireClientArea(out var mainPanelArea);
|
||||
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 />
|
||||
@@ -828,7 +766,10 @@ namespace FlaxEditor.GUI
|
||||
point = _contents.PointFromParent(point);
|
||||
|
||||
// Contents -> Keyframes
|
||||
return PointFromContentsToKeyframes(ref point, ref curveContentAreaBounds);
|
||||
return new Float2(
|
||||
(point.X + _contents.Location.X) / UnitsPerSecond,
|
||||
(point.Y + _contents.Location.Y - curveContentAreaBounds.Height) / -UnitsPerSecond
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -840,7 +781,10 @@ namespace FlaxEditor.GUI
|
||||
protected Float2 PointFromKeyframes(Float2 point, ref Rectangle curveContentAreaBounds)
|
||||
{
|
||||
// Keyframes -> Contents
|
||||
PointFromKeyframesToContents(ref point, ref curveContentAreaBounds);
|
||||
point = new Float2(
|
||||
point.X * UnitsPerSecond - _contents.Location.X,
|
||||
point.Y * -UnitsPerSecond + curveContentAreaBounds.Height - _contents.Location.Y
|
||||
);
|
||||
|
||||
// Contents -> Main Panel
|
||||
point = _contents.PointToParent(point);
|
||||
@@ -849,27 +793,11 @@ namespace FlaxEditor.GUI
|
||||
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)
|
||||
{
|
||||
Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
|
||||
Utilities.Utils.DrawCurveTicks((float tick, float strength) =>
|
||||
{
|
||||
var p = PointFromKeyframes(axis * (float)tick, ref viewRect);
|
||||
var p = PointFromKeyframes(axis * tick, ref viewRect);
|
||||
|
||||
// Draw line
|
||||
var lineRect = new Rectangle
|
||||
@@ -892,24 +820,6 @@ namespace FlaxEditor.GUI
|
||||
}, 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>
|
||||
/// Draws the curve.
|
||||
/// </summary>
|
||||
@@ -939,7 +849,12 @@ namespace FlaxEditor.GUI
|
||||
// Draw time and values axes
|
||||
if (ShowAxes != UseMode.Off)
|
||||
{
|
||||
SetupGrid(out var min, out var max, out var pixelRange);
|
||||
var upperLeft = PointToKeyframes(viewRect.Location, ref viewRect);
|
||||
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);
|
||||
|
||||
@@ -1024,7 +939,7 @@ namespace FlaxEditor.GUI
|
||||
}
|
||||
else if (options.FocusSelection.Process(this))
|
||||
{
|
||||
FocusSelection();
|
||||
ShowWholeCurve();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2285,7 +2200,7 @@ namespace FlaxEditor.GUI
|
||||
|
||||
var tangent = t.TangentValue;
|
||||
var direction = t.IsIn ? -1.0f : 1.0f;
|
||||
var offset = t.TangentOffset;
|
||||
var offset = 30.0f;
|
||||
var location = GetKeyframePoint(ref k, selectedComponent);
|
||||
t.Size = KeyframesSize / ViewScale;
|
||||
t.Location = new Float2
|
||||
@@ -2312,18 +2227,6 @@ 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 />
|
||||
protected override void OnShowContextMenu(ContextMenu.ContextMenu cm, int selectionCount)
|
||||
{
|
||||
|
||||
@@ -486,7 +486,7 @@ namespace FlaxEditor.GUI.Docking
|
||||
{
|
||||
base.Focus();
|
||||
|
||||
SelectTab(false);
|
||||
SelectTab();
|
||||
BringToFront();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
@@ -57,26 +55,18 @@ namespace FlaxEditor.GUI
|
||||
private IsValidDelegate _isValid;
|
||||
private Action<Actor> _selected;
|
||||
|
||||
private ActorSearchPopup(IsValidDelegate isValid, Action<Actor> selected, CustomEditors.IPresenterOwner context)
|
||||
private ActorSearchPopup(IsValidDelegate isValid, Action<Actor> selected)
|
||||
{
|
||||
_isValid = isValid;
|
||||
_selected = selected;
|
||||
|
||||
ItemClicked += OnItemClicked;
|
||||
|
||||
if (context is PropertiesWindow propertiesWindow || context == null)
|
||||
// TODO: use async thread to search scenes
|
||||
for (int i = 0; i < Level.ScenesCount; i++)
|
||||
{
|
||||
// TODO: use async thread to search scenes
|
||||
for (int i = 0; i < Level.ScenesCount; i++)
|
||||
{
|
||||
Find(Level.GetScene(i));
|
||||
}
|
||||
Find(Level.GetScene(i));
|
||||
}
|
||||
else if (context is PrefabWindow prefabWindow)
|
||||
{
|
||||
Find(prefabWindow.Graph.MainActor);
|
||||
}
|
||||
|
||||
SortItems();
|
||||
}
|
||||
|
||||
@@ -108,11 +98,10 @@ namespace FlaxEditor.GUI
|
||||
/// <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="selected">Event called on actor item pick.</param>
|
||||
/// <param name="context">The presenter owner context (i.e. PrefabWindow, PropertiesWindow).</param>
|
||||
/// <returns>The dialog.</returns>
|
||||
public static ActorSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Actor> selected, CustomEditors.IPresenterOwner context)
|
||||
public static ActorSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Actor> selected)
|
||||
{
|
||||
var popup = new ActorSearchPopup(isValid, selected, context);
|
||||
var popup = new ActorSearchPopup(isValid, selected);
|
||||
popup.Show(showTarget, showTargetLocation);
|
||||
return popup;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Utilities;
|
||||
@@ -68,26 +66,18 @@ namespace FlaxEditor.GUI
|
||||
private IsValidDelegate _isValid;
|
||||
private Action<Script> _selected;
|
||||
|
||||
private ScriptSearchPopup(IsValidDelegate isValid, Action<Script> selected, CustomEditors.IPresenterOwner context)
|
||||
private ScriptSearchPopup(IsValidDelegate isValid, Action<Script> selected)
|
||||
{
|
||||
_isValid = isValid;
|
||||
_selected = selected;
|
||||
|
||||
ItemClicked += OnItemClicked;
|
||||
|
||||
if (context is PropertiesWindow propertiesWindow || context == null)
|
||||
// TODO: use async thread to search scenes
|
||||
for (int i = 0; i < Level.ScenesCount; i++)
|
||||
{
|
||||
// TODO: use async thread to search scenes
|
||||
for (int i = 0; i < Level.ScenesCount; i++)
|
||||
{
|
||||
Find(Level.GetScene(i));
|
||||
}
|
||||
Find(Level.GetScene(i));
|
||||
}
|
||||
else if (context is PrefabWindow prefabWindow)
|
||||
{
|
||||
Find(prefabWindow.Graph.MainActor);
|
||||
}
|
||||
|
||||
SortItems();
|
||||
}
|
||||
|
||||
@@ -123,11 +113,10 @@ namespace FlaxEditor.GUI
|
||||
/// <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="selected">Event called on script item pick.</param>
|
||||
/// <param name="context">The presenter owner context (i.e. PrefabWindow, PropertiesWindow).</param>
|
||||
/// <returns>The dialog.</returns>
|
||||
public static ScriptSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Script> selected, CustomEditors.IPresenterOwner context)
|
||||
public static ScriptSearchPopup Show(Control showTarget, Float2 showTargetLocation, IsValidDelegate isValid, Action<Script> selected)
|
||||
{
|
||||
var popup = new ScriptSearchPopup(isValid, selected, context);
|
||||
var popup = new ScriptSearchPopup(isValid, selected);
|
||||
popup.Show(showTarget, showTargetLocation);
|
||||
return popup;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using FlaxEditor.History;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using CategoryAttribute = FlaxEngine.CategoryAttribute;
|
||||
|
||||
namespace FlaxEditor.GUI
|
||||
{
|
||||
@@ -104,26 +101,11 @@ namespace FlaxEditor.GUI
|
||||
if (_isValid(type))
|
||||
{
|
||||
var attributes = type.GetAttributes(true);
|
||||
if (IsHideAttributes(attributes))
|
||||
if (attributes.FirstOrDefault(x => x is HideInEditorAttribute || x is System.Runtime.CompilerServices.CompilerGeneratedAttribute) == null)
|
||||
{
|
||||
var mType = type.Type;
|
||||
if (mType != null)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (mType != null && mType.IsValueType && mType.ReflectedType != null && string.Equals(mType.ReflectedType.Name, "<PrivateImplementationDetails>", StringComparison.Ordinal))
|
||||
continue;
|
||||
AddItem(new TypeItemView(type, attributes));
|
||||
}
|
||||
}
|
||||
@@ -131,17 +113,6 @@ namespace FlaxEditor.GUI
|
||||
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)
|
||||
{
|
||||
_selected(((TypeItemView)item).Type);
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
||||
class Background : ContainerControl
|
||||
{
|
||||
private readonly Timeline _timeline;
|
||||
private double[] _tickSteps;
|
||||
private float[] _tickSteps;
|
||||
private float[] _tickStrengths;
|
||||
private bool _isSelecting;
|
||||
private Float2 _selectingStartPos = Float2.Minimum;
|
||||
@@ -176,9 +176,9 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
||||
// Draw vertical lines for time axis
|
||||
var pixelsInRange = _timeline.Zoom;
|
||||
var pixelRange = pixelsInRange * (max - min);
|
||||
var tickRange = Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
|
||||
var tickRange = Utilities.Utils.DrawCurveTicks((float tick, float strength) =>
|
||||
{
|
||||
var time = (float)tick / _timeline.FramesPerSecond;
|
||||
var time = tick / _timeline.FramesPerSecond;
|
||||
var x = time * zoom + Timeline.StartOffset;
|
||||
var lineColor = style.ForegroundDisabled.RGBMultiplied(0.7f).AlphaMultiplied(strength);
|
||||
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);
|
||||
var lStep = _tickSteps[l];
|
||||
var lNextStep = _tickSteps[l + 1];
|
||||
var startTick = Mathd.FloorToInt(min / lStep);
|
||||
var endTick = Mathd.CeilToInt(max / lStep);
|
||||
int startTick = Mathf.FloorToInt(min / lStep);
|
||||
int endTick = Mathf.CeilToInt(max / lStep);
|
||||
Color lineColor = style.Foreground.RGBMultiplied(0.8f).AlphaMultiplied(strength);
|
||||
Color labelColor = style.ForegroundDisabled.AlphaMultiplied(strength);
|
||||
for (var i = startTick; i <= endTick; i++)
|
||||
for (int i = startTick; i <= endTick; i++)
|
||||
{
|
||||
if (l < biggestTick && (i % Mathd.RoundToInt(lNextStep / lStep) == 0))
|
||||
if (l < biggestTick && (i % Mathf.RoundToInt(lNextStep / lStep) == 0))
|
||||
continue;
|
||||
var tick = (decimal)lStep * i;
|
||||
var time = (double)tick / _timeline.FramesPerSecond;
|
||||
var x = (float)time * zoom + Timeline.StartOffset;
|
||||
var tick = i * lStep;
|
||||
var time = tick / _timeline.FramesPerSecond;
|
||||
var x = time * zoom + Timeline.StartOffset;
|
||||
|
||||
// Header line
|
||||
var lineRect = new Rectangle((float)x - 0.5f, -verticalLinesHeaderExtend * 0.6f + timeAxisHeaderOffset, 1.0f, verticalLinesHeaderExtend * 0.6f);
|
||||
var lineRect = new Rectangle(x - 0.5f, -verticalLinesHeaderExtend * 0.6f + timeAxisHeaderOffset, 1.0f, verticalLinesHeaderExtend * 0.6f);
|
||||
Render2D.FillRectangle(lineRect, lineColor);
|
||||
|
||||
// Time label
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Text;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.Options;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Json;
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
|
||||
private void OnClickedSelect()
|
||||
{
|
||||
ActorSearchPopup.Show(this, PointFromScreen(FlaxEngine.Input.MouseScreenPosition), IsActorValid, SetActor, null);
|
||||
ActorSearchPopup.Show(this, PointFromScreen(FlaxEngine.Input.MouseScreenPosition), IsActorValid, SetActor);
|
||||
}
|
||||
|
||||
private void OnClickedSelectActor(Image image, MouseButton button)
|
||||
|
||||
@@ -19,11 +19,12 @@ namespace FlaxEditor.Gizmo
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct Data
|
||||
{
|
||||
public Matrix WorldMatrix;
|
||||
public Matrix ViewProjectionMatrix;
|
||||
public Float4 GridColor;
|
||||
public Float3 ViewPos;
|
||||
public float Far;
|
||||
public Float3 ViewOrigin;
|
||||
public Float3 Padding;
|
||||
public float GridSize;
|
||||
}
|
||||
|
||||
@@ -43,7 +44,6 @@ namespace FlaxEditor.Gizmo
|
||||
{
|
||||
UseSingleTarget = true;
|
||||
Location = PostProcessEffectLocation.Default;
|
||||
Order = -100000; // Draw before any other editor shapes
|
||||
_shader = FlaxEngine.Content.LoadAsyncInternal<Shader>("Shaders/Editor/Grid");
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace FlaxEditor.Gizmo
|
||||
Profiler.BeginEventGPU("Editor Grid");
|
||||
|
||||
var options = Editor.Instance.Options.Options;
|
||||
Float3 camPos = renderContext.View.WorldPosition;
|
||||
float gridSize = renderContext.View.Far + 20000;
|
||||
|
||||
// Lazy-init resources
|
||||
@@ -96,10 +97,10 @@ namespace FlaxEditor.Gizmo
|
||||
float y = 1.5f; // Add small bias to reduce Z-fighting with geometry at scene origin
|
||||
var vertices = new Float3[]
|
||||
{
|
||||
new Float3(-gridSize, y, -gridSize),
|
||||
new Float3(gridSize, y, gridSize),
|
||||
new Float3(-gridSize, y, gridSize),
|
||||
new Float3(gridSize, y, -gridSize),
|
||||
new Float3(-gridSize + camPos.X, y, -gridSize + camPos.Z),
|
||||
new Float3(gridSize + camPos.X, y, gridSize + camPos.Z),
|
||||
new Float3(-gridSize + camPos.X, y, gridSize + camPos.Z),
|
||||
new Float3(gridSize + camPos.X, y, -gridSize + camPos.Z),
|
||||
};
|
||||
fixed (Float3* ptr = vertices)
|
||||
{
|
||||
@@ -112,12 +113,12 @@ namespace FlaxEditor.Gizmo
|
||||
{
|
||||
var data = new Data();
|
||||
Matrix.Multiply(ref renderContext.View.View, ref renderContext.View.Projection, out var viewProjection);
|
||||
data.WorldMatrix = Matrix.Identity;
|
||||
Matrix.Transpose(ref viewProjection, out data.ViewProjectionMatrix);
|
||||
data.ViewPos = renderContext.View.WorldPosition;
|
||||
data.GridColor = options.Viewport.ViewportGridColor;
|
||||
data.Far = renderContext.View.Far;
|
||||
data.GridSize = options.Viewport.ViewportGridViewDistance;
|
||||
data.ViewOrigin = renderContext.View.Origin;
|
||||
context.UpdateCB(cb, new IntPtr(&data));
|
||||
}
|
||||
|
||||
|
||||
@@ -85,8 +85,6 @@ namespace FlaxEditor.Gizmo
|
||||
/// </summary>
|
||||
public SelectionOutline()
|
||||
{
|
||||
Order = -90000; // Draw before any other editor shapes (except grid gizmo)
|
||||
|
||||
_outlineMaterial = FlaxEngine.Content.LoadAsyncInternal<Material>("Editor/Gizmo/SelectionOutlineMaterial");
|
||||
if (_outlineMaterial)
|
||||
{
|
||||
|
||||
@@ -115,7 +115,6 @@ namespace FlaxEditor.Gizmo
|
||||
bool isCenter = _activeAxis == Axis.Center;
|
||||
renderContext.View.GetWorldMatrix(ref _gizmoWorld, out Matrix world);
|
||||
|
||||
const sbyte sortOrder = 100; // Draw after any other editor shapes
|
||||
const float gizmoModelsScale2RealGizmoSize = 0.075f;
|
||||
Mesh cubeMesh = _modelCube.LODs[0].Meshes[0];
|
||||
Mesh sphereMesh = _modelSphere.LODs[0].Meshes[0];
|
||||
@@ -137,42 +136,42 @@ namespace FlaxEditor.Gizmo
|
||||
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
MaterialInstance xAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
||||
transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3);
|
||||
|
||||
// Y axis
|
||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
MaterialInstance yAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
||||
transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3);
|
||||
|
||||
// Z axis
|
||||
Matrix.RotationX(Mathf.Pi, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
MaterialInstance zAxisMaterialTransform = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
||||
transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3);
|
||||
|
||||
// XY plane
|
||||
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);
|
||||
MaterialInstance xyPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX);
|
||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3);
|
||||
|
||||
// ZX plane
|
||||
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);
|
||||
MaterialInstance zxPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisY);
|
||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3);
|
||||
|
||||
// YZ plane
|
||||
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);
|
||||
MaterialInstance yzPlaneMaterialTransform = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisZ);
|
||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3);
|
||||
|
||||
// Center sphere
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -187,22 +186,22 @@ namespace FlaxEditor.Gizmo
|
||||
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
||||
rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3);
|
||||
|
||||
// Y axis
|
||||
MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
||||
rotationAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m1, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
rotationAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m1);
|
||||
|
||||
// Z axis
|
||||
Matrix.RotationX(-Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
||||
rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3);
|
||||
|
||||
// Center box
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -217,42 +216,42 @@ namespace FlaxEditor.Gizmo
|
||||
Matrix.RotationY(-Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref mx1, out m3);
|
||||
MaterialInstance xAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isXAxis ? _materialAxisFocus : _materialAxisX);
|
||||
scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3);
|
||||
|
||||
// Y axis
|
||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
MaterialInstance yAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isYAxis ? _materialAxisFocus : _materialAxisY);
|
||||
scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3);
|
||||
|
||||
// Z axis
|
||||
Matrix.RotationX(Mathf.Pi, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
MaterialInstance zAxisMaterialRotate = gizmoLocked ? _materialAxisLocked : (isZAxis ? _materialAxisFocus : _materialAxisZ);
|
||||
scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3);
|
||||
|
||||
// XY plane
|
||||
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);
|
||||
MaterialInstance xyPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX);
|
||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3);
|
||||
|
||||
// ZX plane
|
||||
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);
|
||||
MaterialInstance zxPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ);
|
||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3);
|
||||
|
||||
// YZ plane
|
||||
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);
|
||||
MaterialInstance yzPlaneMaterialScale = gizmoLocked ? _materialAxisLocked : (_activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY);
|
||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3);
|
||||
|
||||
// Center box
|
||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -264,7 +263,7 @@ namespace FlaxEditor.Gizmo
|
||||
Transform t = _vertexSnapObject?.Transform ?? _vertexSnapObjectTo.Transform;
|
||||
Vector3 p = t.LocalToWorld(_vertexSnapObject != null ? _vertexSnapPoint : _vertexSnapPointTo);
|
||||
Matrix matrix = new Transform(p, t.Orientation, new Float3(gizmoModelsScale2RealGizmoSize)).GetWorld();
|
||||
cubeMesh.Draw(ref renderContext, _materialSphere, ref matrix, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||
cubeMesh.Draw(ref renderContext, _materialSphere, ref matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,8 +150,7 @@ namespace FlaxEditor
|
||||
private float _mouseMoveSum;
|
||||
private UndoMultiBlock _undoBlock;
|
||||
private View _view;
|
||||
private double[] _gridTickSteps = Utilities.Utils.CurveTickSteps;
|
||||
private float[] _gridTickStrengths;
|
||||
private float[] _gridTickSteps = Utilities.Utils.CurveTickSteps, _gridTickStrengths;
|
||||
private List<Widget> _widgets;
|
||||
private Widget _activeWidget;
|
||||
|
||||
@@ -565,9 +564,9 @@ namespace FlaxEditor
|
||||
var linesColor = style.ForegroundDisabled.RGBMultiplied(0.5f);
|
||||
var labelsColor = style.ForegroundDisabled;
|
||||
var labelsSize = 10.0f;
|
||||
Utilities.Utils.DrawCurveTicks((decimal tick, double step, float strength) =>
|
||||
Utilities.Utils.DrawCurveTicks((float tick, float strength) =>
|
||||
{
|
||||
var p = _view.PointToParent(axis * (float)tick);
|
||||
var p = _view.PointToParent(axis * tick);
|
||||
|
||||
// Draw line
|
||||
var lineRect = new Rectangle
|
||||
|
||||
@@ -504,8 +504,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanSetToRoot(Prefab* prefab, Actor* ta
|
||||
return false;
|
||||
const ISerializable::DeserializeStream& newRootData = **newRootDataPtr;
|
||||
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);
|
||||
if (nestedPrefab && nestedPrefab->GetRootObjectId() != prefabObjectID)
|
||||
@@ -515,6 +514,21 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanSetToRoot(Prefab* prefab, Actor* ta
|
||||
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)
|
||||
{
|
||||
return animatedModel && animatedModel->GraphInstance.State.Count() == 1 ? animatedModel->GraphInstance.State[0].Animation.TimePosition : 0.0f;
|
||||
|
||||
@@ -12,14 +12,11 @@
|
||||
#include "Engine/Scripting/ManagedCLR/MException.h"
|
||||
#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h"
|
||||
#include "Engine/Content/Assets/VisualScript.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/CSG/CSGBuilder.h"
|
||||
#include "Engine/Engine/CommandLine.h"
|
||||
#include "Engine/Renderer/ProbesRenderer.h"
|
||||
#include "Engine/Animations/Graph/AnimGraph.h"
|
||||
#include "Engine/Core/ObjectsRemovalService.h"
|
||||
#include "Engine/Level/Prefabs/Prefab.h"
|
||||
#include "Engine/Serialization/JsonTools.h"
|
||||
|
||||
ManagedEditor::InternalOptions ManagedEditor::ManagedEditorOptions;
|
||||
|
||||
@@ -595,7 +592,6 @@ bool ManagedEditor::EvaluateVisualScriptLocal(VisualScript* script, VisualScript
|
||||
|
||||
void ManagedEditor::WipeOutLeftoverSceneObjects()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
Array<ScriptingObject*> objects = Scripting::GetObjects();
|
||||
bool removedAny = false;
|
||||
for (ScriptingObject* object : objects)
|
||||
@@ -617,21 +613,6 @@ void ManagedEditor::WipeOutLeftoverSceneObjects()
|
||||
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)
|
||||
{
|
||||
ASSERT(!HasManagedInstance());
|
||||
|
||||
@@ -259,7 +259,6 @@ public:
|
||||
API_FUNCTION(Internal) static Array<VisualScriptLocal> GetVisualScriptLocals();
|
||||
API_FUNCTION(Internal) static bool EvaluateVisualScriptLocal(VisualScript* script, API_PARAM(Ref) VisualScriptLocal& local);
|
||||
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:
|
||||
void OnEditorAssemblyLoaded(MAssembly* assembly);
|
||||
|
||||
@@ -21,7 +21,6 @@ namespace FlaxEditor.Modules
|
||||
private bool _enableEvents;
|
||||
private bool _isDuringFastSetup;
|
||||
private bool _rebuildFlag;
|
||||
private bool _rebuildInitFlag;
|
||||
private int _itemsCreated;
|
||||
private int _itemsDeleted;
|
||||
private readonly HashSet<MainContentTreeNode> _dirtyNodes = new HashSet<MainContentTreeNode>();
|
||||
@@ -62,7 +61,7 @@ namespace FlaxEditor.Modules
|
||||
public event Action WorkspaceModified;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when workspace will be rebuilt.
|
||||
/// Occurs when workspace has will be rebuilt.
|
||||
/// </summary>
|
||||
public event Action WorkspaceRebuilding;
|
||||
|
||||
@@ -89,9 +88,6 @@ namespace FlaxEditor.Modules
|
||||
|
||||
// Register AssetItems serialization helper (serialize ref ID only)
|
||||
FlaxEngine.Json.JsonSerializer.Settings.Converters.Add(new AssetItemConverter());
|
||||
|
||||
ScriptsBuilder.ScriptsReload += OnScriptsReload;
|
||||
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
||||
}
|
||||
|
||||
private void OnContentAssetDisposing(Asset asset)
|
||||
@@ -821,7 +817,6 @@ namespace FlaxEditor.Modules
|
||||
Profiler.BeginEvent("ContentDatabase.Rebuild");
|
||||
var startTime = Platform.TimeSeconds;
|
||||
_rebuildFlag = false;
|
||||
_rebuildInitFlag = false;
|
||||
_enableEvents = false;
|
||||
|
||||
// Load all folders
|
||||
@@ -1235,6 +1230,8 @@ namespace FlaxEditor.Modules
|
||||
LoadProjects(Game.Project);
|
||||
}
|
||||
|
||||
RebuildInternal();
|
||||
|
||||
Editor.ContentImporting.ImportFileEnd += (obj, failed) =>
|
||||
{
|
||||
var path = obj.ResultUrl;
|
||||
@@ -1242,15 +1239,6 @@ namespace FlaxEditor.Modules
|
||||
FlaxEngine.Scripting.InvokeOnUpdate(() => OnImportFileDone(path));
|
||||
};
|
||||
_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)
|
||||
@@ -1325,52 +1313,6 @@ 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 />
|
||||
public override void OnUpdate()
|
||||
{
|
||||
@@ -1398,8 +1340,6 @@ namespace FlaxEditor.Modules
|
||||
public override void OnExit()
|
||||
{
|
||||
FlaxEngine.Content.AssetDisposing -= OnContentAssetDisposing;
|
||||
ScriptsBuilder.ScriptsReload -= OnScriptsReload;
|
||||
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||
|
||||
// Disable events
|
||||
_enableEvents = false;
|
||||
|
||||
@@ -391,20 +391,6 @@ namespace FlaxEditor.Modules
|
||||
public override void OnInit()
|
||||
{
|
||||
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 />
|
||||
@@ -465,7 +451,6 @@ namespace FlaxEditor.Modules
|
||||
/// <inheritdoc />
|
||||
public override void OnExit()
|
||||
{
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
EndWorker();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,33 +105,6 @@ namespace FlaxEditor.Modules
|
||||
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)
|
||||
{
|
||||
if (contentItem is PrefabItem prefabItem)
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace FlaxEditor.Modules
|
||||
: base(editor)
|
||||
{
|
||||
// After editor cache but before the windows
|
||||
InitOrder = -800;
|
||||
InitOrder = -900;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -160,7 +160,7 @@ namespace FlaxEditor.Modules
|
||||
internal UIModule(Editor editor)
|
||||
: base(editor)
|
||||
{
|
||||
InitOrder = -70;
|
||||
InitOrder = -90;
|
||||
VisjectSurfaceBackground = FlaxEngine.Content.LoadAsyncInternal<Texture>("Editor/VisjectSurface");
|
||||
ColorValueBox.ShowPickColorDialog += ShowPickColorDialog;
|
||||
}
|
||||
|
||||
@@ -5,12 +5,10 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI.Dialogs;
|
||||
using FlaxEditor.GUI.Docking;
|
||||
using FlaxEditor.Windows;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEditor.Windows.Profiler;
|
||||
@@ -41,7 +39,6 @@ namespace FlaxEditor.Modules
|
||||
|
||||
public DockState DockState;
|
||||
public DockPanel DockedTo;
|
||||
public int DockedTabIndex;
|
||||
public float? SplitterValue = null;
|
||||
|
||||
public bool SelectOnShow = false;
|
||||
@@ -51,8 +48,6 @@ namespace FlaxEditor.Modules
|
||||
public Float2 FloatSize;
|
||||
public Float2 FloatPosition;
|
||||
|
||||
public Guid AssetItemID;
|
||||
|
||||
// Constructor, to allow for default values
|
||||
public WindowRestoreData()
|
||||
{
|
||||
@@ -810,64 +805,43 @@ namespace FlaxEditor.Modules
|
||||
Level.SceneSaving += OnSceneSaving;
|
||||
Level.SceneUnloaded += OnSceneUnloaded;
|
||||
Level.SceneUnloading += OnSceneUnloading;
|
||||
Editor.ContentDatabase.WorkspaceRebuilt += OnWorkspaceRebuilt;
|
||||
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
||||
Editor.StateMachine.StateChanged += OnEditorStateChanged;
|
||||
}
|
||||
|
||||
internal void AddToRestore(AssetEditorWindow win)
|
||||
{
|
||||
AddToRestore(win, win.GetType(), new WindowRestoreData
|
||||
{
|
||||
AssetItemID = win.Item.ID,
|
||||
});
|
||||
}
|
||||
|
||||
internal void AddToRestore(CustomEditorWindow win)
|
||||
{
|
||||
AddToRestore(win.Window, win.GetType(), new WindowRestoreData());
|
||||
}
|
||||
var type = win.GetType();
|
||||
|
||||
private void AddToRestore(EditorWindow win, Type type, WindowRestoreData winData)
|
||||
{
|
||||
// Validate if can restore type
|
||||
var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
|
||||
if (constructor == null || type.IsGenericType)
|
||||
return;
|
||||
|
||||
var panel = win.ParentDockPanel;
|
||||
var winData = new WindowRestoreData();
|
||||
var panel = win.Window.ParentDockPanel;
|
||||
|
||||
// Ensure that this window is only selected following recompilation
|
||||
// if it was the active tab in its dock panel. Otherwise, there is a
|
||||
// risk of interrupting the user's workflow by potentially selecting
|
||||
// background tabs.
|
||||
var window = win.RootWindow.Window;
|
||||
winData.SelectOnShow = panel.SelectedTab == win;
|
||||
winData.DockedTabIndex = 0;
|
||||
if (panel is FloatWindowDockPanel && window != null && panel.TabsCount == 1)
|
||||
winData.SelectOnShow = panel.SelectedTab == win.Window;
|
||||
if (panel is FloatWindowDockPanel)
|
||||
{
|
||||
winData.DockState = DockState.Float;
|
||||
var window = win.Window.RootWindow.Window;
|
||||
winData.FloatPosition = window.Position;
|
||||
winData.FloatSize = window.ClientSize;
|
||||
winData.Maximize = window.IsMaximized;
|
||||
winData.Minimize = window.IsMinimized;
|
||||
winData.DockedTo = panel;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < panel.Tabs.Count; i++)
|
||||
{
|
||||
if (panel.Tabs[i] == win)
|
||||
{
|
||||
winData.DockedTabIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (panel.TabsCount > 1)
|
||||
{
|
||||
winData.DockState = DockState.DockFill;
|
||||
winData.DockedTo = panel;
|
||||
}
|
||||
else
|
||||
}else
|
||||
{
|
||||
winData.DockState = panel.TryGetDockState(out var splitterValue);
|
||||
winData.DockedTo = panel.ParentDockPanel;
|
||||
@@ -879,93 +853,38 @@ namespace FlaxEditor.Modules
|
||||
_restoreWindows.Add(winData);
|
||||
}
|
||||
|
||||
private void OnWorkspaceRebuilt()
|
||||
private void OnScriptsReloadEnd()
|
||||
{
|
||||
// Go in reverse order to create floating Prefab windows first before docked windows
|
||||
for (int i = _restoreWindows.Count - 1; i >= 0; i--)
|
||||
for (int i = 0; i < _restoreWindows.Count; i++)
|
||||
{
|
||||
var winData = _restoreWindows[i];
|
||||
|
||||
try
|
||||
{
|
||||
var assembly = Utils.GetAssemblyByName(winData.AssemblyName);
|
||||
if (assembly == null)
|
||||
continue;
|
||||
|
||||
var type = assembly.GetType(winData.TypeName);
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
if (type.IsAssignableTo(typeof(AssetEditorWindow)))
|
||||
if (assembly != null)
|
||||
{
|
||||
var ctor = type.GetConstructor(new Type[] { typeof(Editor), typeof(AssetItem) });
|
||||
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 type = assembly.GetType(winData.TypeName);
|
||||
if (type != null)
|
||||
{
|
||||
var window = win.RootWindow.Window;
|
||||
window.Position = winData.FloatPosition;
|
||||
if (winData.Maximize)
|
||||
var win = (CustomEditorWindow)Activator.CreateInstance(type);
|
||||
win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue);
|
||||
if (winData.DockState == DockState.Float)
|
||||
{
|
||||
window.Maximize();
|
||||
}
|
||||
else if (winData.Minimize)
|
||||
{
|
||||
window.Minimize();
|
||||
}
|
||||
else
|
||||
{
|
||||
window.ClientSize = winData.FloatSize;
|
||||
}
|
||||
|
||||
// Update panel reference in other windows docked to this panel
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -976,11 +895,6 @@ namespace FlaxEditor.Modules
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -1136,7 +1050,7 @@ namespace FlaxEditor.Modules
|
||||
Level.SceneSaving -= OnSceneSaving;
|
||||
Level.SceneUnloaded -= OnSceneUnloaded;
|
||||
Level.SceneUnloading -= OnSceneUnloading;
|
||||
Editor.ContentDatabase.WorkspaceRebuilt -= OnWorkspaceRebuilt;
|
||||
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||
Editor.StateMachine.StateChanged -= OnEditorStateChanged;
|
||||
|
||||
// Close main window
|
||||
|
||||
@@ -8,7 +8,6 @@ using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using static FlaxEditor.Viewport.EditorViewport;
|
||||
|
||||
namespace FlaxEditor.Options
|
||||
{
|
||||
@@ -19,7 +18,7 @@ namespace FlaxEditor.Options
|
||||
[HideInEditor]
|
||||
[TypeConverter(typeof(InputBindingConverter))]
|
||||
[CustomEditor(typeof(InputBindingEditor))]
|
||||
public struct InputBinding : IEquatable<InputBinding>
|
||||
public struct InputBinding
|
||||
{
|
||||
/// <summary>
|
||||
/// The key to bind.
|
||||
@@ -252,40 +251,6 @@ namespace FlaxEditor.Options
|
||||
}
|
||||
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
|
||||
@@ -557,27 +522,5 @@ namespace FlaxEditor.Options
|
||||
|
||||
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,32 +7,6 @@ using FlaxEngine;
|
||||
|
||||
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>
|
||||
/// Input editor options data container.
|
||||
/// </summary>
|
||||
@@ -370,10 +344,6 @@ namespace FlaxEditor.Options
|
||||
[EditorDisplay("Interface"), EditorOrder(2020)]
|
||||
public InputBinding PreviousTab = new InputBinding(KeyboardKeys.Tab, KeyboardKeys.Control, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(SceneNodeDoubleClick.Expand)]
|
||||
[EditorDisplay("Interface"), EditorOrder(2030)]
|
||||
public SceneNodeDoubleClick DoubleClickSceneNode = SceneNodeDoubleClick.Expand;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace FlaxEditor.Options
|
||||
/// <summary>
|
||||
/// Focus the Game Window. On play mode end restore focus to the previous window.
|
||||
/// </summary>
|
||||
GameWindowThenRestore,
|
||||
GameWindowThenRestore,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -379,22 +379,6 @@ 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>
|
||||
/// Gets or sets a value indicating whether auto-focus output log window on code compilation error.
|
||||
/// </summary>
|
||||
|
||||
@@ -8,7 +8,6 @@ using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI;
|
||||
using FlaxEditor.GUI.Drag;
|
||||
using FlaxEditor.GUI.Tree;
|
||||
using FlaxEditor.Options;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEditor.Windows;
|
||||
@@ -16,6 +15,7 @@ using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using FlaxEngine.Utilities;
|
||||
using Object = FlaxEngine.Object;
|
||||
|
||||
namespace FlaxEditor.SceneGraph.GUI
|
||||
{
|
||||
@@ -393,7 +393,7 @@ namespace FlaxEditor.SceneGraph.GUI
|
||||
/// <summary>
|
||||
/// Starts the actor renaming action.
|
||||
/// </summary>
|
||||
public void StartRenaming(EditorWindow window = null, Panel treePanel = null)
|
||||
public void StartRenaming(EditorWindow window, Panel treePanel = null)
|
||||
{
|
||||
// Block renaming during scripts reload
|
||||
if (Editor.Instance.ProgressReporting.CompileScripts.IsActive)
|
||||
@@ -461,30 +461,6 @@ 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 />
|
||||
protected override DragDropEffect OnDragEnterHeader(DragData data)
|
||||
{
|
||||
|
||||
@@ -469,7 +469,6 @@ namespace FlaxEditor.SceneGraph
|
||||
{
|
||||
ChildNodes[i].OnDispose();
|
||||
}
|
||||
ChildNodes.Clear();
|
||||
|
||||
SceneGraphFactory.Nodes.Remove(ID);
|
||||
}
|
||||
|
||||
@@ -161,8 +161,6 @@ namespace FlaxEditor.Surface
|
||||
|
||||
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
|
||||
bool hasTypeFromGameScripts = Editor.Instance.CodeEditing.AnimGraphNodes.HasTypeFromGameScripts;
|
||||
|
||||
|
||||
@@ -1182,9 +1182,9 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DrawEditorGrid(ref Rectangle rect)
|
||||
public override void DrawEditorBackground(ref Rectangle rect)
|
||||
{
|
||||
base.DrawEditorGrid(ref rect);
|
||||
base.DrawEditorBackground(ref rect);
|
||||
|
||||
// Draw triangulated multi blend space
|
||||
var style = Style.Current;
|
||||
@@ -1195,8 +1195,15 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
else
|
||||
Render2D.FillTriangles(_triangles, style.TextBoxBackgroundSelected.AlphaMultiplied(0.6f));
|
||||
Render2D.DrawTriangles(_triangles, style.Foreground);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DrawEditorGrid(ref Rectangle rect)
|
||||
{
|
||||
base.DrawEditorGrid(ref rect);
|
||||
|
||||
// Highlight selected blend point
|
||||
var style = Style.Current;
|
||||
var selectedIndex = _selectedAnimation.SelectedIndex;
|
||||
if (selectedIndex != -1 && selectedIndex < _editor.BlendPoints.Count && (ContainsFocus || IsMouseOver))
|
||||
{
|
||||
|
||||
@@ -87,17 +87,11 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
private class GradientStop : Control
|
||||
{
|
||||
private bool _isMoving;
|
||||
private float _movedToTime = float.MaxValue;
|
||||
private Float2 _startMovePos;
|
||||
|
||||
public ColorGradientNode Node;
|
||||
public Color Color;
|
||||
|
||||
public void UpdateLocation(float time)
|
||||
{
|
||||
Location = Node._gradient.BottomLeft + new Float2(time * Node._gradient.Width - Width * 0.5f, 0.0f);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw()
|
||||
{
|
||||
@@ -124,7 +118,6 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
if (button == MouseButton.Left)
|
||||
{
|
||||
Node.Select(this);
|
||||
_movedToTime = float.MaxValue;
|
||||
_isMoving = true;
|
||||
_startMovePos = location;
|
||||
StartMouseCapture();
|
||||
@@ -140,12 +133,6 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
if (button == MouseButton.Left && _isMoving)
|
||||
{
|
||||
_isMoving = false;
|
||||
if (_movedToTime < float.MaxValue)
|
||||
{
|
||||
int index = Node._stops.IndexOf(this);
|
||||
Node.SetStopTime(index, _movedToTime);
|
||||
_movedToTime = float.MaxValue;
|
||||
}
|
||||
EndMouseCapture();
|
||||
}
|
||||
|
||||
@@ -172,10 +159,9 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
if (_isMoving && Float2.DistanceSquared(ref location, ref _startMovePos) > 25.0f)
|
||||
{
|
||||
_startMovePos = Float2.Minimum;
|
||||
int index = Node._stops.IndexOf(this);
|
||||
_movedToTime = (PointToParent(location).X - Node._gradient.BottomLeft.X) / Node._gradient.Width;
|
||||
_movedToTime = Node.ClampStopTime(index, _movedToTime);
|
||||
UpdateLocation(_movedToTime);
|
||||
var index = Node._stops.IndexOf(this);
|
||||
var time = (PointToParent(location).X - Node._gradient.BottomLeft.X) / Node._gradient.Width;
|
||||
Node.SetStopTime(index, time);
|
||||
}
|
||||
|
||||
base.OnMouseMove(location);
|
||||
@@ -185,7 +171,6 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
public override void OnEndMouseCapture()
|
||||
{
|
||||
_isMoving = false;
|
||||
_movedToTime = float.MaxValue;
|
||||
|
||||
base.OnEndMouseCapture();
|
||||
}
|
||||
@@ -238,7 +223,6 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
Parent = this
|
||||
};
|
||||
_timeValue.ValueChanged += OnTimeValueChanged;
|
||||
_timeValue.SlidingEnd += OnTimeValueChanged;
|
||||
|
||||
_colorValue = new ColorValueBox(Color.Black, _timeValue.Right + 4.0f, controlsLevel)
|
||||
{
|
||||
@@ -317,16 +301,8 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
|
||||
private void OnTimeValueChanged()
|
||||
{
|
||||
var time = _timeValue.Value;
|
||||
var index = _stops.IndexOf(_selected);
|
||||
if (_timeValue.IsSliding)
|
||||
{
|
||||
// Preview-only while sliding
|
||||
time = ClampStopTime(index, time);
|
||||
_selected.UpdateLocation(time);
|
||||
return;
|
||||
}
|
||||
SetStopTime(index, time);
|
||||
SetStopTime(index, _timeValue.Value);
|
||||
}
|
||||
|
||||
private void OnColorValueChanged()
|
||||
@@ -370,7 +346,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
UpdateStops();
|
||||
}
|
||||
|
||||
private float ClampStopTime(int index, float time)
|
||||
private void SetStopTime(int index, float time)
|
||||
{
|
||||
time = Mathf.Saturate(time);
|
||||
if (index != 0)
|
||||
@@ -381,12 +357,6 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -425,7 +395,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
{
|
||||
var stop = _stops[i];
|
||||
var time = (float)Values[i * 2 + 1];
|
||||
stop.UpdateLocation(time);
|
||||
stop.Location = _gradient.BottomLeft + new Float2(time * _gradient.Width - stop.Width * 0.5f, 0.0f);
|
||||
stop.Color = (Color)Values[i * 2 + 2];
|
||||
stop.TooltipText = stop.Color + " at " + time;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace FlaxEditor.Surface
|
||||
public BehaviorTreeSurface(IVisjectSurfaceOwner owner, Action onSave, FlaxEditor.Undo undo)
|
||||
: base(owner, onSave, undo, CreateStyle())
|
||||
{
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
private static SurfaceStyle CreateStyle()
|
||||
@@ -36,11 +35,6 @@ namespace FlaxEditor.Surface
|
||||
return style;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
_nodesCache.Clear();
|
||||
}
|
||||
|
||||
private static void DrawBox(Box box)
|
||||
{
|
||||
var rect = new Rectangle(Float2.Zero, box.Size);
|
||||
@@ -192,7 +186,6 @@ namespace FlaxEditor.Surface
|
||||
{
|
||||
if (IsDisposing)
|
||||
return;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
_nodesCache.Wait();
|
||||
|
||||
base.OnDestroy();
|
||||
|
||||
@@ -415,15 +415,6 @@ namespace FlaxEditor.Surface
|
||||
// Init drag handlers
|
||||
DragHandlers.Add(_dragAssets = new DragAssets<DragDropEventArgs>(ValidateDragItem));
|
||||
DragHandlers.Add(_dragParameters = new DragNames<DragDropEventArgs>(SurfaceParameter.DragPrefix, ValidateDragParameter));
|
||||
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
_activeVisjectCM = null;
|
||||
_cmPrimaryMenu?.Dispose();
|
||||
_cmPrimaryMenu = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1032,8 +1023,6 @@ namespace FlaxEditor.Surface
|
||||
_activeVisjectCM = null;
|
||||
_cmPrimaryMenu?.Dispose();
|
||||
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,12 +62,6 @@ namespace FlaxEditor.Surface
|
||||
{
|
||||
_supportsImplicitCastFromObjectToBoolean = true;
|
||||
DragHandlers.Add(_dragActors = new DragActors(ValidateDragActor));
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
_nodesCache.Clear();
|
||||
}
|
||||
|
||||
private bool ValidateDragActor(ActorNode actor)
|
||||
@@ -637,7 +631,6 @@ namespace FlaxEditor.Surface
|
||||
{
|
||||
if (IsDisposing)
|
||||
return;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
_nodesCache.Wait();
|
||||
|
||||
base.OnDestroy();
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace FlaxEditor.Actions
|
||||
public Guid PrefabID;
|
||||
public Guid PrefabObjectID;
|
||||
|
||||
public Item(SceneObject obj, List<Item> nestedPrefabLinks)
|
||||
public unsafe Item(SceneObject obj, List<Item> nestedPrefabLinks)
|
||||
{
|
||||
ID = obj.ID;
|
||||
PrefabID = obj.PrefabID;
|
||||
@@ -33,7 +33,8 @@ namespace FlaxEditor.Actions
|
||||
// Check if this object comes from another nested prefab (to break link only from the top-level prefab)
|
||||
Item nested;
|
||||
nested.ID = ID;
|
||||
Editor.GetPrefabNestedObject(ref PrefabID, ref PrefabObjectID, out nested.PrefabID, out nested.PrefabObjectID);
|
||||
fixed (Item* i = &this)
|
||||
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)
|
||||
nestedPrefabLinks.Add(nested);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace FlaxEditor
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">The type of the data. Must have <see cref="SerializableAttribute"/>.</typeparam>
|
||||
/// <seealso cref="FlaxEditor.IUndoAction" />
|
||||
[Serializable, HideInEditor]
|
||||
[Serializable]
|
||||
public abstract class UndoActionBase<TData> : IUndoAction where TData : struct
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace FlaxEditor.Utilities;
|
||||
/// <summary>
|
||||
/// Units display utilities for Editor.
|
||||
/// </summary>
|
||||
public static class Units
|
||||
public class Units
|
||||
{
|
||||
/// <summary>
|
||||
/// Factor of units per meter.
|
||||
|
||||
@@ -236,19 +236,19 @@ namespace FlaxEditor.Utilities
|
||||
/// <summary>
|
||||
/// The time/value axes tick steps for editors with timeline.
|
||||
/// </summary>
|
||||
internal static readonly double[] CurveTickSteps =
|
||||
internal static readonly float[] CurveTickSteps =
|
||||
{
|
||||
0.0000001, 0.0000005, 0.000001, 0.000005, 0.00001,
|
||||
0.00005, 0.0001, 0.0005, 0.001, 0.005,
|
||||
0.01, 0.05, 0.1, 0.5, 1,
|
||||
0.0000001f, 0.0000005f, 0.000001f, 0.000005f, 0.00001f,
|
||||
0.00005f, 0.0001f, 0.0005f, 0.001f, 0.005f,
|
||||
0.01f, 0.05f, 0.1f, 0.5f, 1,
|
||||
5, 10, 50, 100, 500,
|
||||
1000, 5000, 10000, 50000, 100000,
|
||||
500000, 1000000, 5000000, 10000000, 100000000
|
||||
};
|
||||
|
||||
internal delegate void DrawCurveTick(decimal tick, double step, float strength);
|
||||
internal delegate void DrawCurveTick(float tick, float strength);
|
||||
|
||||
internal static Int2 DrawCurveTicks(DrawCurveTick drawTick, double[] tickSteps, ref float[] tickStrengths, float min, float max, float pixelRange, float minDistanceBetweenTicks = 20, float maxDistanceBetweenTicks = 60)
|
||||
internal static Int2 DrawCurveTicks(DrawCurveTick drawTick, float[] tickSteps, ref float[] tickStrengths, float min, float max, float pixelRange, float minDistanceBetweenTicks = 20, float maxDistanceBetweenTicks = 60)
|
||||
{
|
||||
if (pixelRange <= Mathf.Epsilon || maxDistanceBetweenTicks <= minDistanceBetweenTicks)
|
||||
return Int2.Zero;
|
||||
@@ -262,10 +262,10 @@ namespace FlaxEditor.Utilities
|
||||
for (int i = tickSteps.Length - 1; i >= 0; i--)
|
||||
{
|
||||
// Calculate how far apart these modulo tick steps are spaced
|
||||
var tickSpacing = tickSteps[i] * pixelsInRange;
|
||||
float tickSpacing = tickSteps[i] * pixelsInRange;
|
||||
|
||||
// Calculate the strength of the tick markers based on the spacing
|
||||
tickStrengths[i] = (float)Mathd.Saturate((tickSpacing - minDistanceBetweenTicks) / (maxDistanceBetweenTicks - minDistanceBetweenTicks));
|
||||
tickStrengths[i] = Mathf.Saturate((tickSpacing - minDistanceBetweenTicks) / (maxDistanceBetweenTicks - minDistanceBetweenTicks));
|
||||
|
||||
// Beyond threshold the ticks don't get any bigger or fatter
|
||||
if (tickStrengths[i] >= 1)
|
||||
@@ -283,7 +283,7 @@ namespace FlaxEditor.Utilities
|
||||
// Draw all tick levels
|
||||
for (int level = 0; level < tickLevels; level++)
|
||||
{
|
||||
var strength = tickStrengths[smallestTick + level];
|
||||
float strength = tickStrengths[smallestTick + level];
|
||||
if (strength <= Mathf.Epsilon)
|
||||
continue;
|
||||
|
||||
@@ -291,36 +291,20 @@ namespace FlaxEditor.Utilities
|
||||
int l = Mathf.Clamp(smallestTick + level, 0, tickSteps.Length - 2);
|
||||
var lStep = tickSteps[l];
|
||||
var lNextStep = tickSteps[l + 1];
|
||||
var startTick = Mathd.FloorToInt(min / lStep);
|
||||
var endTick = Mathd.CeilToInt(max / lStep);
|
||||
for (var i = startTick; i <= endTick; i++)
|
||||
int startTick = Mathf.FloorToInt(min / lStep);
|
||||
int endTick = Mathf.CeilToInt(max / lStep);
|
||||
for (int i = startTick; i <= endTick; i++)
|
||||
{
|
||||
if (l < biggestTick && (i % Mathd.RoundToInt(lNextStep / lStep) == 0))
|
||||
if (l < biggestTick && (i % Mathf.RoundToInt(lNextStep / lStep) == 0))
|
||||
continue;
|
||||
var tick = (decimal)lStep * i;
|
||||
drawTick(tick, lStep, strength);
|
||||
var tick = i * lStep;
|
||||
drawTick(tick, strength);
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
/// Determines whether the specified path string contains any invalid character.
|
||||
/// </summary>
|
||||
@@ -1544,12 +1528,5 @@ namespace FlaxEditor.Utilities
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
internal static ISceneContextWindow GetSceneContext(this Control c)
|
||||
{
|
||||
while (c != null && !(c is ISceneContextWindow))
|
||||
c = c.Parent;
|
||||
return c as ISceneContextWindow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.Gizmo;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Viewport.Cameras;
|
||||
using FlaxEditor.Viewport.Previews;
|
||||
using FlaxEditor.Viewport.Widgets;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
@@ -46,7 +44,7 @@ namespace FlaxEditor.Viewport
|
||||
private sealed class PrefabUIEditorRoot : UIEditorRoot
|
||||
{
|
||||
private readonly PrefabWindowViewport _viewport;
|
||||
private bool UI => _viewport.ShowUI;
|
||||
private bool UI => _viewport._hasUILinkedCached;
|
||||
|
||||
public PrefabUIEditorRoot(PrefabWindowViewport viewport)
|
||||
: base(true)
|
||||
@@ -69,78 +67,8 @@ namespace FlaxEditor.Viewport
|
||||
private PrefabSpritesRenderer _spritesRenderer;
|
||||
private IntPtr _tempDebugDrawContext;
|
||||
|
||||
private bool _hasUILinkedCached;
|
||||
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>
|
||||
/// Drag and drop handlers
|
||||
@@ -210,11 +138,6 @@ namespace FlaxEditor.Viewport
|
||||
_uiRoot.IndexInParent = 0; // Move viewport down below other widgets in the viewport
|
||||
_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);
|
||||
|
||||
// Setup input actions
|
||||
@@ -223,8 +146,58 @@ namespace FlaxEditor.Viewport
|
||||
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)
|
||||
{
|
||||
UpdateGizmoMode();
|
||||
for (int i = 0; i < Gizmos.Count; i++)
|
||||
{
|
||||
Gizmos[i].Update(deltaTime);
|
||||
|
||||
@@ -58,8 +58,6 @@ namespace FlaxEditor.Windows.Assets
|
||||
InputActions.Add(options => options.Save, Save);
|
||||
|
||||
UpdateTitle();
|
||||
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -153,8 +151,6 @@ namespace FlaxEditor.Windows.Assets
|
||||
/// <inheritdoc />
|
||||
public override void OnDestroy()
|
||||
{
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
|
||||
if (_item != null)
|
||||
{
|
||||
// Ensure to remove linkage to the item
|
||||
@@ -164,15 +160,6 @@ namespace FlaxEditor.Windows.Assets
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected virtual void OnScriptsReloadBegin()
|
||||
{
|
||||
if (!IsHidden)
|
||||
{
|
||||
Editor.Instance.Windows.AddToRestore(this);
|
||||
}
|
||||
}
|
||||
|
||||
#region IEditable Implementation
|
||||
|
||||
private bool _isEdited;
|
||||
|
||||
@@ -268,11 +268,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
UpdateKnowledge();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnScriptsReloadBegin()
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
base.OnScriptsReloadBegin();
|
||||
|
||||
// TODO: impl hot-reload for BT to nicely refresh state (save asset, clear undo/properties, reload surface)
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
ViewportCamera = new FPSCamera(),
|
||||
Parent = _split.Panel1
|
||||
};
|
||||
_preview.Task.ViewFlags &= ~ViewFlags.Sky & ~ViewFlags.Bloom & ~ViewFlags.EyeAdaptation;
|
||||
_preview.Task.ViewFlags &= ~ViewFlags.Sky & ~ViewFlags.Bloom;
|
||||
|
||||
// Asset properties
|
||||
_propertiesPresenter = new CustomEditorPresenter(null);
|
||||
|
||||
@@ -124,10 +124,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
UpdateToolstrip();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnScriptsReloadBegin()
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
base.OnScriptsReloadBegin();
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FlaxEditor.Content;
|
||||
using FlaxEditor.GUI.ContextMenu;
|
||||
using FlaxEditor.GUI.Drag;
|
||||
@@ -85,7 +86,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Actors.Get().Contains(actorType);
|
||||
}
|
||||
|
||||
|
||||
private static bool ValidateDragControlType(ScriptType controlType)
|
||||
{
|
||||
return Editor.Instance.CodeEditing.Controls.Get().Contains(controlType);
|
||||
@@ -170,8 +171,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
var actor = item.OnEditorDrop(this);
|
||||
actor.Name = item.ShortName;
|
||||
_window.Spawn(actor);
|
||||
var graphNode = _window.Graph.Root.Find(actor);
|
||||
;
|
||||
var graphNode = _window.Graph.Root.Find(actor);;
|
||||
if (graphNode != null)
|
||||
graphNodes.Add(graphNode);
|
||||
}
|
||||
@@ -235,8 +235,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
actor.Name = actorType.Name;
|
||||
_window.Spawn(actor);
|
||||
var graphNode = _window.Graph.Root.Find(actor);
|
||||
;
|
||||
var graphNode = _window.Graph.Root.Find(actor);;
|
||||
if (graphNode != null)
|
||||
graphNodes.Add(graphNode);
|
||||
}
|
||||
@@ -291,7 +290,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
// Basic editing options
|
||||
|
||||
var b = contextMenu.AddButton("Rename", RenameSelection);
|
||||
var b = contextMenu.AddButton("Rename", Rename);
|
||||
b.Enabled = isSingleActorSelected;
|
||||
|
||||
b = contextMenu.AddButton("Duplicate", Duplicate);
|
||||
@@ -415,8 +414,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
contextMenu.Show(parent, location);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RenameSelection()
|
||||
private void Rename()
|
||||
{
|
||||
var selection = Selection;
|
||||
if (selection.Count != 0 && selection[0] is ActorNode actor)
|
||||
@@ -427,12 +425,6 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void FocusSelection()
|
||||
{
|
||||
_viewport.FocusSelection();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns the specified actor to the prefab (adds actor to root).
|
||||
/// </summary>
|
||||
@@ -476,7 +468,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
// Spawn it
|
||||
Spawn(actor);
|
||||
RenameSelection();
|
||||
Rename();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
/// </summary>
|
||||
/// <seealso cref="Prefab" />
|
||||
/// <seealso cref="FlaxEditor.Windows.Assets.AssetEditorWindow" />
|
||||
public sealed partial class PrefabWindow : AssetEditorWindowBase<Prefab>, IPresenterOwner, ISceneContextWindow
|
||||
public sealed partial class PrefabWindow : AssetEditorWindowBase<Prefab>, IPresenterOwner
|
||||
{
|
||||
private readonly SplitPanel _split1;
|
||||
private readonly SplitPanel _split2;
|
||||
@@ -194,6 +194,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
Editor.Prefabs.PrefabApplied += OnPrefabApplied;
|
||||
ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin;
|
||||
ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd;
|
||||
|
||||
// Setup input actions
|
||||
InputActions.Add(options => options.Undo, () =>
|
||||
@@ -211,8 +212,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
InputActions.Add(options => options.Paste, Paste);
|
||||
InputActions.Add(options => options.Duplicate, Duplicate);
|
||||
InputActions.Add(options => options.Delete, Delete);
|
||||
InputActions.Add(options => options.Rename, RenameSelection);
|
||||
InputActions.Add(options => options.FocusSelection, FocusSelection);
|
||||
InputActions.Add(options => options.Rename, Rename);
|
||||
InputActions.Add(options => options.FocusSelection, _viewport.FocusSelection);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -286,10 +287,8 @@ namespace FlaxEditor.Windows.Assets
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnScriptsReloadBegin()
|
||||
private void OnScriptsReloadBegin()
|
||||
{
|
||||
base.OnScriptsReloadBegin();
|
||||
_isScriptsReloading = true;
|
||||
|
||||
if (_asset == null || !_asset.IsLoaded)
|
||||
@@ -317,8 +316,19 @@ namespace FlaxEditor.Windows.Assets
|
||||
Graph.MainActor = null;
|
||||
_viewport.Prefab = null;
|
||||
_undo?.Clear(); // TODO: maybe don't clear undo?
|
||||
}
|
||||
|
||||
Close();
|
||||
private void OnScriptsReloadEnd()
|
||||
{
|
||||
_isScriptsReloading = false;
|
||||
|
||||
if (_asset == null || !_asset.IsLoaded)
|
||||
return;
|
||||
|
||||
// Restore
|
||||
OnPrefabOpened();
|
||||
_undo.Clear();
|
||||
ClearEditedFlag();
|
||||
}
|
||||
|
||||
private void OnUndoEvent(IUndoAction action)
|
||||
@@ -345,22 +355,13 @@ namespace FlaxEditor.Windows.Assets
|
||||
private void OnPrefabOpened()
|
||||
{
|
||||
_viewport.Prefab = _asset;
|
||||
if (Editor.ProjectCache.TryGetCustomData($"UIMode:{_asset.ID}", out bool value))
|
||||
_viewport.SetInitialUIMode(value);
|
||||
else
|
||||
_viewport.SetInitialUIMode(_viewport._hasUILinked);
|
||||
_viewport.UIModeToggled += OnUIModeToggled;
|
||||
_viewport.UpdateGizmoMode();
|
||||
Graph.MainActor = _viewport.Instance;
|
||||
Selection.Clear();
|
||||
Select(Graph.Main);
|
||||
Graph.Root.TreeNode.Expand(true);
|
||||
}
|
||||
|
||||
private void OnUIModeToggled(bool value)
|
||||
{
|
||||
Editor.ProjectCache.SetCustomData($"UIMode:{_asset.ID}", value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Save()
|
||||
{
|
||||
@@ -537,6 +538,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
{
|
||||
Editor.Prefabs.PrefabApplied -= OnPrefabApplied;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||
|
||||
_undo.Dispose();
|
||||
Graph.Dispose();
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace FlaxEditor.Windows
|
||||
private const string ProjectDataLastViewedFolder = "LastViewedFolder";
|
||||
private bool _isWorkspaceDirty;
|
||||
private string _workspaceRebuildLocation;
|
||||
private string _lastViewedFolderBeforeReload;
|
||||
private SplitPanel _split;
|
||||
private Panel _contentViewPanel;
|
||||
private Panel _contentTreePanel;
|
||||
@@ -145,6 +144,26 @@ namespace FlaxEditor.Windows
|
||||
|
||||
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;
|
||||
options.OptionsChanged += OnOptionsChanged;
|
||||
|
||||
@@ -1017,61 +1036,6 @@ namespace FlaxEditor.Windows
|
||||
|
||||
/// <inheritdoc />
|
||||
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
|
||||
_root = new RootContentTreeNode
|
||||
@@ -1108,6 +1072,13 @@ namespace FlaxEditor.Windows
|
||||
// Update UI layout
|
||||
_isLayoutLocked = false;
|
||||
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 />
|
||||
@@ -1255,8 +1226,6 @@ namespace FlaxEditor.Windows
|
||||
_viewDropdown = null;
|
||||
|
||||
Editor.Options.OptionsChanged -= OnOptionsChanged;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd;
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
@@ -95,15 +95,15 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
case LogType.Warning:
|
||||
Group = LogGroup.Warning;
|
||||
Icon = _window._iconWarning;
|
||||
Icon = _window.IconWarning;
|
||||
break;
|
||||
case LogType.Info:
|
||||
Group = LogGroup.Info;
|
||||
Icon = _window._iconInfo;
|
||||
Icon = _window.IconInfo;
|
||||
break;
|
||||
default:
|
||||
Group = LogGroup.Error;
|
||||
Icon = _window._iconError;
|
||||
Icon = _window.IconError;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -131,21 +131,20 @@ namespace FlaxEditor.Windows
|
||||
else if (index % 2 == 0)
|
||||
Render2D.FillRectangle(clientRect, style.Background * 0.9f);
|
||||
|
||||
var color = Group == LogGroup.Error ? _window._colorError : (Group == LogGroup.Warning ? _window._colorWarning : _window._colorInfo);
|
||||
|
||||
// Icon
|
||||
Render2D.DrawSprite(Icon, new Rectangle(5, 0, 32, 32), color);
|
||||
var iconColor = Group == LogGroup.Error ? Color.Red : (Group == LogGroup.Warning ? Color.Yellow : style.Foreground);
|
||||
Render2D.DrawSprite(Icon, new Rectangle(5, 0, 32, 32), iconColor);
|
||||
|
||||
// Title
|
||||
var textRect = new Rectangle(38, 2, clientRect.Width - 40, clientRect.Height - 10);
|
||||
Render2D.PushClip(ref clientRect);
|
||||
if (LogCount == 1)
|
||||
{
|
||||
Render2D.DrawText(style.FontMedium, Desc.Title, textRect, color);
|
||||
Render2D.DrawText(style.FontMedium, Desc.Title, textRect, style.Foreground);
|
||||
}
|
||||
else if (LogCount > 1)
|
||||
{
|
||||
Render2D.DrawText(style.FontMedium, $"{Desc.Title} ({LogCount})", textRect, color);
|
||||
Render2D.DrawText(style.FontMedium, $"{Desc.Title} ({LogCount})", textRect, style.Foreground);
|
||||
}
|
||||
Render2D.PopClip();
|
||||
}
|
||||
@@ -305,12 +304,10 @@ namespace FlaxEditor.Windows
|
||||
private readonly ToolStripButton[] _groupButtons = new ToolStripButton[3];
|
||||
|
||||
private LogType _iconType = LogType.Info;
|
||||
private SpriteHandle _iconInfo;
|
||||
private SpriteHandle _iconWarning;
|
||||
private SpriteHandle _iconError;
|
||||
private Color _colorInfo;
|
||||
private Color _colorWarning;
|
||||
private Color _colorError;
|
||||
|
||||
internal SpriteHandle IconInfo;
|
||||
internal SpriteHandle IconWarning;
|
||||
internal SpriteHandle IconError;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DebugLogWindow"/> class.
|
||||
@@ -320,7 +317,7 @@ namespace FlaxEditor.Windows
|
||||
: base(editor, true, ScrollBars.None)
|
||||
{
|
||||
Title = "Debug Log";
|
||||
Icon = _iconInfo;
|
||||
Icon = IconInfo;
|
||||
FlaxEditor.Utilities.Utils.SetupCommonInputActions(this);
|
||||
|
||||
// Toolstrip
|
||||
@@ -364,6 +361,7 @@ namespace FlaxEditor.Windows
|
||||
editor.Options.Apply(editor.Options.Options);
|
||||
}).SetAutoCheck(true).LinkTooltip("Shows/hides info messages");
|
||||
UpdateCount();
|
||||
OnEditorOptionsChanged(Editor.Options.Options);
|
||||
|
||||
// Split panel
|
||||
_split = new SplitPanel(Orientation.Vertical, ScrollBars.Vertical, ScrollBars.Both)
|
||||
@@ -396,17 +394,14 @@ namespace FlaxEditor.Windows
|
||||
};
|
||||
|
||||
// Cache entries icons
|
||||
_iconInfo = Editor.Icons.Info64;
|
||||
_iconWarning = Editor.Icons.Warning64;
|
||||
_iconError = Editor.Icons.Error64;
|
||||
IconInfo = Editor.Icons.Info64;
|
||||
IconWarning = Editor.Icons.Warning64;
|
||||
IconError = Editor.Icons.Error64;
|
||||
|
||||
// Bind events
|
||||
Editor.Options.OptionsChanged += OnEditorOptionsChanged;
|
||||
Debug.Logger.LogHandler.SendLog += LogHandlerOnSendLog;
|
||||
Debug.Logger.LogHandler.SendExceptionLog += LogHandlerOnSendExceptionLog;
|
||||
|
||||
// Init editor options
|
||||
OnEditorOptionsChanged(Editor.Options.Options);
|
||||
}
|
||||
|
||||
private void OnEditorOptionsChanged(EditorOptions options)
|
||||
@@ -418,9 +413,6 @@ namespace FlaxEditor.Windows
|
||||
_groupButtons[0].Checked = options.Interface.DebugLogShowErrorMessages;
|
||||
_groupButtons[1].Checked = options.Interface.DebugLogShowWarningMessages;
|
||||
_groupButtons[2].Checked = options.Interface.DebugLogShowInfoMessages;
|
||||
_colorInfo = options.Interface.OutputLogTextColor;
|
||||
_colorWarning = options.Interface.OutputLogWarningTextColor;
|
||||
_colorError = options.Interface.OutputLogErrorTextColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -430,6 +422,7 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
if (_entriesPanel == null)
|
||||
return;
|
||||
|
||||
RemoveEntries();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace FlaxEditor.Windows
|
||||
private readonly GameRoot _guiRoot;
|
||||
private bool _showGUI = true;
|
||||
private bool _showDebugDraw = false;
|
||||
private bool _audioMuted = false;
|
||||
private float _audioVolume = 1;
|
||||
private bool _isMaximized = false, _isUnlockingMouse = false;
|
||||
private bool _isFloating = false, _isBorderless = false;
|
||||
private bool _cursorVisible = true;
|
||||
@@ -93,35 +91,6 @@ namespace FlaxEditor.Windows
|
||||
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>
|
||||
/// Gets or sets a value indicating whether the game window is maximized (only in play mode).
|
||||
/// </summary>
|
||||
@@ -677,24 +646,6 @@ namespace FlaxEditor.Windows
|
||||
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.AddSeparator();
|
||||
}
|
||||
|
||||
@@ -286,9 +286,7 @@ namespace FlaxEditor.Windows
|
||||
_output.DefaultStyle.Font == options.Interface.OutputLogTextFont &&
|
||||
_output.DefaultStyle.Color == options.Interface.OutputLogTextColor &&
|
||||
_output.DefaultStyle.ShadowColor == options.Interface.OutputLogTextShadowColor &&
|
||||
_output.DefaultStyle.ShadowOffset == options.Interface.OutputLogTextShadowOffset &&
|
||||
_output.WarningStyle.Color == options.Interface.OutputLogWarningTextColor &&
|
||||
_output.ErrorStyle.Color == options.Interface.OutputLogErrorTextColor)
|
||||
_output.DefaultStyle.ShadowOffset == options.Interface.OutputLogTextShadowOffset)
|
||||
return;
|
||||
|
||||
_output.DefaultStyle = new TextBlockStyle
|
||||
@@ -299,11 +297,10 @@ namespace FlaxEditor.Windows
|
||||
ShadowOffset = options.Interface.OutputLogTextShadowOffset,
|
||||
BackgroundSelectedBrush = new SolidColorBrush(Style.Current.BackgroundSelected),
|
||||
};
|
||||
|
||||
_output.WarningStyle = _output.DefaultStyle;
|
||||
_output.WarningStyle.Color = options.Interface.OutputLogWarningTextColor;
|
||||
_output.WarningStyle.Color = Color.Yellow;
|
||||
_output.ErrorStyle = _output.DefaultStyle;
|
||||
_output.ErrorStyle.Color = options.Interface.OutputLogErrorTextColor;
|
||||
_output.ErrorStyle.Color = Color.Red;
|
||||
|
||||
_timestampsFormats = options.Interface.OutputLogTimestampsFormat;
|
||||
_showLogType = options.Interface.OutputLogShowLogType;
|
||||
@@ -604,7 +601,7 @@ namespace FlaxEditor.Windows
|
||||
var cachedScrollValue = _vScroll.Value;
|
||||
var cachedSelection = _output.SelectionRange;
|
||||
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.TargetViewOffset = cachedOutputTargetViewOffset;
|
||||
_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