60 Commits
wip ... sdl_wip

Author SHA1 Message Date
3554747a67 Fix window dragging when not supported by Wayland compositor
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
2025-02-02 18:36:03 +02:00
62968dd437 Show current display server in Editor window tooltip 2025-02-02 18:34:47 +02:00
c660fac524 Properly mark floating windows with transparency support 2025-02-02 13:38:15 +02:00
431a69e357 Enable transparency support in Vulkan swapchains 2025-02-01 22:31:50 +02:00
f4fcc07288 Fix compilation for game builds
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled
2025-01-29 16:17:27 +02:00
a38cc4d5cb Fix cloning SDL repository
Some checks are pending
Build Android / Game (Android, Release ARM64) (push) Waiting to run
Build iOS / Game (iOS, Release ARM64) (push) Waiting to run
Build Linux / Editor (Linux, Development x64) (push) Waiting to run
Build Linux / Game (Linux, Release x64) (push) Waiting to run
Build macOS / Editor (Mac, Development ARM64) (push) Waiting to run
Build macOS / Game (Mac, Release ARM64) (push) Waiting to run
Build Windows / Editor (Windows, Development x64) (push) Waiting to run
Build Windows / Game (Windows, Release x64) (push) Waiting to run
Cooker / Cook (Mac) (push) Waiting to run
Tests / Tests (Linux) (push) Waiting to run
Tests / Tests (Windows) (push) Waiting to run
2025-01-28 22:41:45 +02:00
1528d458d9 Fix text input not working on X11 2025-01-28 22:08:17 +02:00
9e937776ac Apply patches to rapidjson 2025-01-28 22:08:16 +02:00
a8aebdd01f Update rapidjson to latest version
Commit d621dc9e9c77f81e5c8a35b8dcc16dcd63351321 in Tencent/rapidjson
2025-01-28 22:08:16 +02:00
998ed87029 Fix button latching on Windows after drag and drop operation 2025-01-28 22:08:16 +02:00
279b3f8d9a Implement new window dragging system 2025-01-28 22:08:15 +02:00
738a506b6d Fix mouse resetting issues after ending relative mode 2025-01-28 22:08:15 +02:00
0ddecdda1f Fix frame stutter when window is focused 2025-01-28 22:08:14 +02:00
94a22907e2 Fix error when docking to sides of tabbed panel 2025-01-28 22:08:14 +02:00
d22a0aad0c Cleanup Linux SDL implementation 2025-01-28 22:08:14 +02:00
9e035f3818 Support compiling third party library C files as C code 2025-01-28 22:08:13 +02:00
99a810458a Implement Wayland protocols module and file generation 2025-01-28 22:08:13 +02:00
2806578126 Fix mouse warping after ending relative mode 2025-01-28 22:08:13 +02:00
882e9a6623 Add git fetch method for dependencies 2025-01-28 22:08:12 +02:00
14c156e351 Fix window ShowInTaskbar setting 2025-01-28 22:08:12 +02:00
cd2151332e Fix various issues with child window positioning 2025-01-28 22:08:12 +02:00
53bbca3779 Add Window.IsAlwaysOnTop property 2025-01-28 22:08:11 +02:00
51f4ac467e Use SDL locale 2025-01-28 22:08:11 +02:00
81427a7f9e Allow window with single tab to be dragged from tab area 2025-01-28 22:08:10 +02:00
faadfb28b3 Fix ValueBox mouse position resetting after releasing the button 2025-01-28 22:08:10 +02:00
6bfe0bed35 Fix SDL build process on Linux 2025-01-28 22:08:10 +02:00
6e4d5b853f Update SDL to 3.2.0 2025-01-28 22:08:09 +02:00
0ebe23b482 _sdl binary 2025-01-28 22:08:09 +02:00
abbde5861a Update SDL3 binaries 2025-01-28 22:08:08 +02:00
b78d4349a7 _lfsconfig 2025-01-28 22:08:08 +02:00
3c1d3234b8 Force cursor to center of Game Window when tab handle is clicked 2025-01-28 22:08:07 +02:00
Chandler Cox
79baaae8e7 Fix rotation using SDL 2025-01-28 22:08:07 +02:00
79289662ed Fix Linux compilation without SDL 2025-01-28 22:08:07 +02:00
89a2985ad8 Fix compilation 2025-01-28 22:08:06 +02:00
1f0a521a87 Update SDL3 2025-01-28 22:08:06 +02:00
8a0e43c38c Fix compilation issues 2025-01-28 22:08:06 +02:00
ac9022f585 Fix windows not being hidden initially 2025-01-28 22:08:05 +02:00
314dbbbeaf Fix parent window position handling with popup/tooltip windows 2025-01-28 22:08:05 +02:00
f13e09910d Fix compilation errors in other platforms 2025-01-28 22:08:04 +02:00
67b9511afe Fix CI for Linux 2025-01-28 22:08:04 +02:00
510c477468 Prevent building with SDL in unsupported platforms 2025-01-28 22:08:04 +02:00
697fcc18ab Fallback to X11 message box implementation when SDL fails 2025-01-28 22:08:03 +02:00
89ff08b3f2 Fix popup and context menus not working on Wayland 2025-01-28 22:08:03 +02:00
9417585cd9 Hide warnings for unsupported SDL operations on Wayland 2025-01-28 22:08:03 +02:00
f794bb5455 Log a warning for not implemented Wayland functionality 2025-01-28 22:08:02 +02:00
bb7a5326cd Fix compilation in Linux 2025-01-28 22:08:02 +02:00
a998b2a44e Enable warning sound in question dialogs 2025-01-28 22:08:02 +02:00
a69eb4296f Enable modern Windows dialog boxes 2025-01-28 22:08:01 +02:00
727af5a5b9 Implement relative mouse mode (raw input) for SDL platform 2025-01-28 22:08:01 +02:00
d545dd8219 Add flag for Window types 2025-01-28 22:08:00 +02:00
29e385ab4b Enable native windowing system settings with SDL platform 2025-01-28 22:08:00 +02:00
5c63e30b84 Add command-line switches to force X11 and Wayland SDL drivers 2025-01-28 22:08:00 +02:00
5187c677f1 Implement SDL platform, windowing and input handling 2025-01-28 22:07:59 +02:00
1d43314efd Refactor application window class name 2025-01-28 22:07:59 +02:00
91ef8c69db Move Window related enums to separate header file 2025-01-28 22:07:59 +02:00
f24251af82 Refactor Windows drag and drop implementation 2025-01-28 22:07:58 +02:00
ed6e0138e6 Refactor ScreenUtilities 2025-01-28 22:07:58 +02:00
4362cdb396 Add more helper methods for managing Git repos 2025-01-28 22:07:57 +02:00
8146680b53 Fix centered window location on X11 2025-01-28 22:07:57 +02:00
27aa2cfa1f Fix initial position of Tooltips 2025-01-28 22:07:57 +02:00
285 changed files with 1729 additions and 3956 deletions

View File

@@ -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

View File

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

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

View File

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

View File

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

View File

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

View File

@@ -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)
{

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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"));

View File

@@ -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()
{

View File

@@ -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;
}
}

View File

@@ -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 />

View File

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

View File

@@ -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 />

View File

@@ -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
{

View File

@@ -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;
}

View File

@@ -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()
{

View File

@@ -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)

View File

@@ -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>

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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)
{

View File

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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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)

View File

@@ -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));
}

View File

@@ -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)
{

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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());

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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)

View File

@@ -58,7 +58,7 @@ namespace FlaxEditor.Modules
: base(editor)
{
// After editor cache but before the windows
InitOrder = -800;
InitOrder = -900;
}
/// <summary>

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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
}
}

View File

@@ -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>

View File

@@ -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)
{

View File

@@ -469,7 +469,6 @@ namespace FlaxEditor.SceneGraph
{
ChildNodes[i].OnDispose();
}
ChildNodes.Clear();
SceneGraphFactory.Nodes.Remove(ID);
}

View File

@@ -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;

View File

@@ -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))
{

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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();
}
}

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -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.

View File

@@ -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;
}
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -124,10 +124,8 @@ namespace FlaxEditor.Windows.Assets
UpdateToolstrip();
}
/// <inheritdoc />
protected override void OnScriptsReloadBegin()
private void OnScriptsReloadBegin()
{
base.OnScriptsReloadBegin();
Close();
}

View File

@@ -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>

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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