5 Commits

Author SHA1 Message Date
6e61233a7b _rider improvement
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-10-29 23:03:01 +02:00
bf59455412 _zed macos final
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-10-29 21:13:20 +02:00
a016b9d47b _rider macos
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-10-29 20:44:34 +02:00
7bdc08f8be _macos? 2025-10-29 20:43:50 +02:00
269e8963e8 Add support for Zed code editor
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-10-29 20:16:05 +02:00
662 changed files with 6539 additions and 105328 deletions

View File

@@ -31,7 +31,7 @@ body:
- '1.10' - '1.10'
- '1.11' - '1.11'
- master branch - master branch
default: 3 default: 2
validations: validations:
required: true required: true
- type: textarea - type: textarea

View File

@@ -16,7 +16,7 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Setup Vulkan - name: Setup Vulkan
uses: ./.github/actions/vulkan uses: ./.github/actions/vulkan
- name: Setup .NET - name: Setup .NET
@@ -44,7 +44,7 @@ jobs:
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev libwayland-dev sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev
- name: Setup Vulkan - name: Setup Vulkan
uses: ./.github/actions/vulkan uses: ./.github/actions/vulkan
- name: Setup .NET - name: Setup .NET

View File

@@ -28,7 +28,7 @@ jobs:
git lfs pull git lfs pull
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev libwayland-dev sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Build - name: Build
run: | run: |
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8 ./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8

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

Binary file not shown.

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

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

View File

@@ -4,7 +4,7 @@
"Major": 1, "Major": 1,
"Minor": 11, "Minor": 11,
"Revision": 0, "Revision": 0,
"Build": 6805 "Build": 6802
}, },
"Company": "Flax", "Company": "Flax",
"Copyright": "Copyright (c) 2012-2025 Wojciech Figat. All rights reserved.", "Copyright": "Copyright (c) 2012-2025 Wojciech Figat. All rights reserved.",
@@ -13,7 +13,6 @@
"Configuration": { "Configuration": {
"UseCSharp": true, "UseCSharp": true,
"UseLargeWorlds": false, "UseLargeWorlds": false,
"UseDotNet": true, "UseDotNet": true
"UseSDL": true
} }
} }

View File

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

View File

@@ -282,7 +282,7 @@ namespace FlaxEditor.Content
if (data is DragDataFiles) if (data is DragDataFiles)
return DragDropEffect.Copy; return DragDropEffect.Copy;
return _dragOverItems?.Effect ?? DragDropEffect.None; return _dragOverItems.Effect;
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -749,7 +749,7 @@ namespace FlaxEditor.Content
} }
// Draw short name // Draw short name
Render2D.PushClip(textRect); Render2D.PushClip(ref textRect);
var scale = 0.95f * view.ViewScale; var scale = 0.95f * view.ViewScale;
Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, scale); Render2D.DrawText(style.FontMedium, ShowFileExtension || view.ShowFileExtensions ? FileName : ShortName, textRect, style.Foreground, nameAlignment, TextAlignment.Center, TextWrapping.WrapWords, 1f, scale);
Render2D.PopClip(); Render2D.PopClip();

View File

@@ -20,7 +20,7 @@ namespace FlaxEditor.Content
} }
/// <inheritdoc /> /// <inheritdoc />
public override string TypeDescription => Path.EndsWith(".h") || Path.EndsWith(".hpp") ? "C++ Header File" : "C++ Source Code"; public override string TypeDescription => Path.EndsWith(".h") ? "C++ Header File" : "C++ Source Code";
/// <inheritdoc /> /// <inheritdoc />
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CPPScript128; public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CPPScript128;

View File

@@ -281,13 +281,6 @@ namespace FlaxEditor.Content
private void CacheData() private void CacheData()
{ {
if (!_asset)
{
_parameters = Utils.GetEmptyArray<ScriptMemberInfo>();
_methods = Utils.GetEmptyArray<ScriptMemberInfo>();
_attributes = Utils.GetEmptyArray<Attribute>();
return;
}
if (_parameters != null) if (_parameters != null)
return; return;
if (_asset.WaitForLoaded()) if (_asset.WaitForLoaded())
@@ -351,13 +344,13 @@ namespace FlaxEditor.Content
} }
/// <inheritdoc /> /// <inheritdoc />
public string Name => _asset ? Path.GetFileNameWithoutExtension(_asset.Path) : null; public string Name => Path.GetFileNameWithoutExtension(_asset.Path);
/// <inheritdoc /> /// <inheritdoc />
public string Namespace => string.Empty; public string Namespace => string.Empty;
/// <inheritdoc /> /// <inheritdoc />
public string TypeName => _asset ? JsonSerializer.GetStringID(_asset.ID) : null; public string TypeName => JsonSerializer.GetStringID(_asset.ID);
/// <inheritdoc /> /// <inheritdoc />
public bool IsPublic => true; public bool IsPublic => true;

View File

@@ -263,7 +263,7 @@ namespace FlaxEditor.Content.Thumbnails
// Create render task but disabled for now // Create render task but disabled for now
_output = GPUDevice.Instance.CreateTexture("ThumbnailsOutput"); _output = GPUDevice.Instance.CreateTexture("ThumbnailsOutput");
var desc = GPUTextureDescription.New2D(PreviewsCache.AssetIconSize, PreviewsCache.AssetIconSize, PreviewsCache.AssetIconsAtlasFormat); var desc = GPUTextureDescription.New2D(PreviewsCache.AssetIconSize, PreviewsCache.AssetIconSize, PreviewsCache.AssetIconsAtlasFormat);
_output.Init(desc); _output.Init(ref desc);
_task = Object.New<RenderTask>(); _task = Object.New<RenderTask>();
_task.Order = 50; // Render this task later _task.Order = 50; // Render this task later
_task.Enabled = false; _task.Enabled = false;

View File

@@ -15,32 +15,26 @@
#include "Editor/ProjectInfo.h" #include "Editor/ProjectInfo.h"
#include "Editor/Utilities/EditorUtilities.h" #include "Editor/Utilities/EditorUtilities.h"
String GetGDK() GDKPlatformTools::GDKPlatformTools()
{ {
String gdk; // Find GDK
Platform::GetEnvironmentVariable(TEXT("GameDKLatest"), gdk); Platform::GetEnvironmentVariable(TEXT("GameDKLatest"), _gdkPath);
if (gdk.IsEmpty() || !FileSystem::DirectoryExists(gdk)) if (_gdkPath.IsEmpty() || !FileSystem::DirectoryExists(_gdkPath))
{ {
gdk.Clear(); _gdkPath.Clear();
Platform::GetEnvironmentVariable(TEXT("GRDKLatest"), gdk); Platform::GetEnvironmentVariable(TEXT("GRDKLatest"), _gdkPath);
if (gdk.IsEmpty() || !FileSystem::DirectoryExists(gdk)) if (_gdkPath.IsEmpty() || !FileSystem::DirectoryExists(_gdkPath))
{ {
gdk.Clear(); _gdkPath.Clear();
} }
else else
{ {
if (gdk.EndsWith(TEXT("GRDK\\"))) if (_gdkPath.EndsWith(TEXT("GRDK\\")))
gdk.Remove(gdk.Length() - 6); _gdkPath.Remove(_gdkPath.Length() - 6);
else if (gdk.EndsWith(TEXT("GRDK"))) else if (_gdkPath.EndsWith(TEXT("GRDK")))
gdk.Remove(gdk.Length() - 5); _gdkPath.Remove(_gdkPath.Length() - 5);
} }
} }
return gdk;
}
GDKPlatformTools::GDKPlatformTools()
{
_gdkPath = GetGDK();
} }
DotNetAOTModes GDKPlatformTools::UseAOT() const DotNetAOTModes GDKPlatformTools::UseAOT() const
@@ -127,7 +121,7 @@ bool GDKPlatformTools::OnPostProcess(CookingData& data, GDKPlatformSettings* pla
validName.Add('\0'); validName.Add('\0');
sb.Append(TEXT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")); sb.Append(TEXT("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"));
sb.Append(TEXT("<Game configVersion=\"1\">\n")); sb.Append(TEXT("<Game configVersion=\"0\">\n"));
sb.AppendFormat(TEXT(" <Identity Name=\"{0}\" Publisher=\"{1}\" Version=\"{2}\"/>\n"), sb.AppendFormat(TEXT(" <Identity Name=\"{0}\" Publisher=\"{1}\" Version=\"{2}\"/>\n"),
validName.Get(), validName.Get(),
platformSettings->PublisherName.HasChars() ? platformSettings->PublisherName : TEXT("CN=") + gameSettings->CompanyName, platformSettings->PublisherName.HasChars() ? platformSettings->PublisherName : TEXT("CN=") + gameSettings->CompanyName,

View File

@@ -10,10 +10,9 @@
#include "Engine/Serialization/JsonTools.h" #include "Engine/Serialization/JsonTools.h"
#include "Engine/Serialization/JsonWriters.h" #include "Engine/Serialization/JsonWriters.h"
#include "Editor/Cooker/PlatformTools.h" #include "Editor/Cooker/PlatformTools.h"
#include "Engine/Engine/Globals.h"
#include "Editor/Editor.h" #include "Editor/Editor.h"
#include "Editor/ProjectInfo.h" #include "Editor/ProjectInfo.h"
#include "Editor/Utilities/EditorUtilities.h" #include "Engine/Engine/Globals.h"
#if PLATFORM_MAC #if PLATFORM_MAC
#include <sys/stat.h> #include <sys/stat.h>
#endif #endif
@@ -128,7 +127,7 @@ bool CompileScriptsStep::DeployBinaries(CookingData& data, const String& path, c
const String dst = dstPath / StringUtils::GetFileName(file); const String dst = dstPath / StringUtils::GetFileName(file);
if (dst == file) if (dst == file)
continue; continue;
if (EditorUtilities::CopyFileIfNewer(dst, file)) if (FileSystem::CopyFile(dst, file))
{ {
data.Error(String::Format(TEXT("Failed to copy file from {0} to {1}."), file, dst)); data.Error(String::Format(TEXT("Failed to copy file from {0} to {1}."), file, dst));
return true; return true;

View File

@@ -526,7 +526,6 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass
#if PLATFORM_TOOLS_XBOX_SCARLETT #if PLATFORM_TOOLS_XBOX_SCARLETT
case BuildPlatform::XboxScarlett: case BuildPlatform::XboxScarlett:
{ {
options.Platform = PlatformType::XboxScarlett;
const char* platformDefineName = "PLATFORM_XBOX_SCARLETT"; const char* platformDefineName = "PLATFORM_XBOX_SCARLETT";
COMPILE_PROFILE(DirectX_SM6, SHADER_FILE_CHUNK_INTERNAL_D3D_SM6_CACHE); COMPILE_PROFILE(DirectX_SM6, SHADER_FILE_CHUNK_INTERNAL_D3D_SM6_CACHE);
break; break;
@@ -1368,10 +1367,7 @@ bool CookAssetsStep::Perform(CookingData& data)
{ {
typeName = e.TypeName; typeName = e.TypeName;
} }
if (e.Count == 1) LOG(Info, "{0}: {1:>4} assets of total size {2}", typeName, e.Count, Utilities::BytesToText(e.ContentSize));
LOG(Info, "{0}: 1 asset of total size {1}", typeName, Utilities::BytesToText(e.ContentSize));
else
LOG(Info, "{0}: {1:>4} assets of total size {2}", typeName, e.Count, Utilities::BytesToText(e.ContentSize));
} }
LOG(Info, ""); LOG(Info, "");
} }

View File

@@ -265,7 +265,7 @@ bool DeployDataStep::Perform(CookingData& data)
} }
if (version.IsEmpty()) if (version.IsEmpty())
{ {
data.Error(String::Format(TEXT("Failed to find supported .NET {} version (min {}) for {} platform."), maxVer, minVer, platformName)); data.Error(String::Format(TEXT("Failed to find supported .NET {} version (min {}) for the current host platform."), maxVer, minVer));
return true; return true;
} }
} }

View File

@@ -59,7 +59,6 @@ bool PrecompileAssembliesStep::Perform(CookingData& data)
data.StepProgress(infoMsg, 0); data.StepProgress(infoMsg, 0);
// Override Newtonsoft.Json with AOT-version (one that doesn't use System.Reflection.Emit) // Override Newtonsoft.Json with AOT-version (one that doesn't use System.Reflection.Emit)
// TODO: remove it since EngineModule does properly reference AOT lib now
EditorUtilities::CopyFileIfNewer(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.dll"), Globals::StartupFolder / TEXT("Source/Platforms/DotNet/AOT/Newtonsoft.Json.dll")); EditorUtilities::CopyFileIfNewer(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.dll"), Globals::StartupFolder / TEXT("Source/Platforms/DotNet/AOT/Newtonsoft.Json.dll"));
FileSystem::DeleteFile(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.xml")); FileSystem::DeleteFile(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.xml"));
FileSystem::DeleteFile(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.pdb")); FileSystem::DeleteFile(data.ManagedCodeOutputPath / TEXT("Newtonsoft.Json.pdb"));

View File

@@ -60,14 +60,14 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (prefab && !prefab.WaitForLoaded()) if (prefab && !prefab.WaitForLoaded())
{ {
var prefabObjectId = actor.PrefabObjectID; var prefabObjectId = actor.PrefabObjectID;
var prefabInstance = prefab.GetDefaultInstance(prefabObjectId); var prefabInstance = prefab.GetDefaultInstance(ref prefabObjectId);
if (prefabInstance != null) if (prefabInstance != null)
{ {
// Use default prefab instance as a reference for the editor // Use default prefab instance as a reference for the editor
Values.SetReferenceValue(prefabInstance); Values.SetReferenceValue(prefabInstance);
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs) // Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
prefab.GetNestedObject(prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId); prefab.GetNestedObject(ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId); var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId);
var panel = layout.UniformGrid(); var panel = layout.UniformGrid();
panel.CustomControl.Height = 20.0f; panel.CustomControl.Height = 20.0f;
@@ -207,7 +207,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
{ {
var actor = (Actor)Values[0]; var actor = (Actor)Values[0];
var prefabObjectId = actor.PrefabObjectID; var prefabObjectId = actor.PrefabObjectID;
var prefabInstance = prefab.GetDefaultInstance(prefabObjectId); var prefabInstance = prefab.GetDefaultInstance(ref prefabObjectId);
if (prefabInstance != null) if (prefabInstance != null)
{ {
Values.SetReferenceValue(prefabInstance); Values.SetReferenceValue(prefabInstance);
@@ -525,7 +525,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
var restored = actor.AddScript(removed.PrefabObject.GetType()); var restored = actor.AddScript(removed.PrefabObject.GetType());
var prefabId = actor.PrefabID; var prefabId = actor.PrefabID;
var prefabObjectId = restored.PrefabObjectID; var prefabObjectId = restored.PrefabObjectID;
Script.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), prefabId, prefabObjectId); Script.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), ref prefabId, ref prefabObjectId);
string data = JsonSerializer.Serialize(removed.PrefabObject); string data = JsonSerializer.Serialize(removed.PrefabObject);
JsonSerializer.Deserialize(restored, data); JsonSerializer.Deserialize(restored, data);
@@ -547,7 +547,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
string data = JsonSerializer.Serialize(removedActor.PrefabObject); string data = JsonSerializer.Serialize(removedActor.PrefabObject);
JsonSerializer.Deserialize(restored, data); JsonSerializer.Deserialize(restored, data);
Presenter.Owner.SceneContext.Spawn(restored, parentActor, removedActor.OrderInParent); Presenter.Owner.SceneContext.Spawn(restored, parentActor, removedActor.OrderInParent);
Actor.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), prefabId, prefabObjectId); Actor.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), ref prefabId, ref prefabObjectId);
return; return;
} }

View File

@@ -1,7 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved. // Copyright (c) Wojciech Figat. All rights reserved.
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.CustomEditors.Dedicated namespace FlaxEditor.CustomEditors.Dedicated
{ {
@@ -12,7 +11,7 @@ namespace FlaxEditor.CustomEditors.Dedicated
[CustomEditor(typeof(EnvironmentProbe)), DefaultEditor] [CustomEditor(typeof(EnvironmentProbe)), DefaultEditor]
public class EnvironmentProbeEditor : ActorEditor public class EnvironmentProbeEditor : ActorEditor
{ {
private Button _bake; private FlaxEngine.GUI.Button _bake;
/// <inheritdoc /> /// <inheritdoc />
public override void Initialize(LayoutElementsContainer layout) public override void Initialize(LayoutElementsContainer layout)
@@ -21,9 +20,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (Values.HasDifferentTypes == false) if (Values.HasDifferentTypes == false)
{ {
var group = layout.Group("Bake"); layout.Space(10);
group.Panel.ItemsMargin = new Margin(Utilities.Constants.UIMargin * 2); _bake = layout.Button("Bake").Button;
_bake = group.Button("Bake").Button;
_bake.Clicked += BakeButtonClicked; _bake.Clicked += BakeButtonClicked;
} }
} }

View File

@@ -190,12 +190,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
foreach (var file in files) foreach (var file in files)
FindNewKeysCSharp(file, newKeys, allKeys); FindNewKeysCSharp(file, newKeys, allKeys);
// C/C++ // C++
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.cpp", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.c", SearchOption.AllDirectories)).ToArray(); files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.cpp", SearchOption.AllDirectories);
filesCount += files.Length; filesCount += files.Length;
foreach (var file in files) foreach (var file in files)
FindNewKeysCpp(file, newKeys, allKeys); FindNewKeysCpp(file, newKeys, allKeys);
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.hpp", SearchOption.AllDirectories)).ToArray();; files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories);
filesCount += files.Length; filesCount += files.Length;
foreach (var file in files) foreach (var file in files)
FindNewKeysCpp(file, newKeys, allKeys); FindNewKeysCpp(file, newKeys, allKeys);

View File

@@ -164,11 +164,11 @@ namespace FlaxEditor.CustomEditors.Dedicated
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14); var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
// Deselect // Deselect
if (isSelected && button1Rect.Contains(location)) if (isSelected && button1Rect.Contains(ref location))
Value = new ModelInstanceActor.MeshReference { Actor = null, LODIndex = -1, MeshIndex = -1 }; Value = new ModelInstanceActor.MeshReference { Actor = null, LODIndex = -1, MeshIndex = -1 };
// Picker dropdown menu // Picker dropdown menu
if ((isSelected ? button2Rect : button1Rect).Contains(location)) if ((isSelected ? button2Rect : button1Rect).Contains(ref location))
ShowDropDownMenu(); ShowDropDownMenu();
return base.OnMouseUp(location, button); return base.OnMouseUp(location, button);

View File

@@ -40,7 +40,7 @@ public class ModelPrefabEditor : GenericEditor
if (prefab) if (prefab)
{ {
var prefabObjectId = modelPrefab.PrefabObjectID; var prefabObjectId = modelPrefab.PrefabObjectID;
var prefabObject = prefab.GetDefaultInstance(prefabObjectId); var prefabObject = prefab.GetDefaultInstance(ref prefabObjectId);
if (prefabObject.PrefabID == _prefabId) if (prefabObject.PrefabID == _prefabId)
break; break;
_prefabId = prefabObject.PrefabID; _prefabId = prefabObject.PrefabID;

View File

@@ -914,11 +914,9 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Remove drop down arrows and containment lines if no objects in the group // Remove drop down arrows and containment lines if no objects in the group
if (group.Children.Count == 0) if (group.Children.Count == 0)
{ {
group.Panel.Close();
group.Panel.ArrowImageOpened = null; group.Panel.ArrowImageOpened = null;
group.Panel.ArrowImageClosed = null; group.Panel.ArrowImageClosed = null;
group.Panel.EnableContainmentLines = false; group.Panel.EnableContainmentLines = false;
group.Panel.CanOpenClose = false;
} }
// Scripts arrange bar // Scripts arrange bar

View File

@@ -1,7 +1,6 @@
// Copyright (c) Wojciech Figat. All rights reserved. // Copyright (c) Wojciech Figat. All rights reserved.
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.CustomEditors.Dedicated namespace FlaxEditor.CustomEditors.Dedicated
{ {
@@ -20,9 +19,8 @@ namespace FlaxEditor.CustomEditors.Dedicated
if (Values.HasDifferentTypes == false) if (Values.HasDifferentTypes == false)
{ {
// Add 'Bake' button // Add 'Bake' button
var group = layout.Group("Bake"); layout.Space(10);
group.Panel.ItemsMargin = new Margin(Utilities.Constants.UIMargin * 2); var button = layout.Button("Bake");
var button = group.Button("Bake");
button.Button.Clicked += BakeButtonClicked; button.Button.Clicked += BakeButtonClicked;
} }
} }

View File

@@ -123,8 +123,6 @@ namespace FlaxEditor.CustomEditors.Editors
{ {
base.Refresh(); base.Refresh();
if (Picker == null)
return;
var differentValues = HasDifferentValues; var differentValues = HasDifferentValues;
Picker.DifferentValues = differentValues; Picker.DifferentValues = differentValues;
if (!differentValues) if (!differentValues)
@@ -192,7 +190,7 @@ namespace FlaxEditor.CustomEditors.Editors
public override bool OnMouseDown(Float2 location, MouseButton button) public override bool OnMouseDown(Float2 location, MouseButton button)
{ {
if (DropdownRect.Contains(location)) if (DropdownRect.Contains(ref location))
{ {
Focus(); Focus();
ShowPicker(); ShowPicker();
@@ -206,7 +204,7 @@ namespace FlaxEditor.CustomEditors.Editors
{ {
base.OnMouseMove(location); base.OnMouseMove(location);
if (DropdownRect.Contains(location)) if (DropdownRect.Contains(ref location))
Cursor = CursorType.Default; Cursor = CursorType.Default;
else else
Cursor = CursorType.IBeam; Cursor = CursorType.IBeam;

View File

@@ -155,7 +155,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button) public override bool OnMouseDown(Float2 location, MouseButton button)
{ {
if (button == MouseButton.Left && _arrangeButtonRect.Contains(location)) if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
{ {
_arrangeButtonInUse = true; _arrangeButtonInUse = true;
Focus(); Focus();
@@ -371,7 +371,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button) public override bool OnMouseDown(Float2 location, MouseButton button)
{ {
if (button == MouseButton.Left && _arrangeButtonRect.Contains(location)) if (button == MouseButton.Left && _arrangeButtonRect.Contains(ref location))
{ {
_arrangeButtonInUse = true; _arrangeButtonInUse = true;
Focus(); Focus();
@@ -650,7 +650,7 @@ namespace FlaxEditor.CustomEditors.Editors
panel.Panel.Size = new Float2(0, 18); panel.Panel.Size = new Float2(0, 18);
panel.Panel.Margin = new Margin(0, 0, Utilities.Constants.UIMargin, 0); panel.Panel.Margin = new Margin(0, 0, Utilities.Constants.UIMargin, 0);
var removeButton = panel.Button("-", "Remove the last item."); var removeButton = panel.Button("-", "Remove the last item");
removeButton.Button.Size = new Float2(16, 16); removeButton.Button.Size = new Float2(16, 16);
removeButton.Button.Enabled = size > _minCount; removeButton.Button.Enabled = size > _minCount;
removeButton.Button.AnchorPreset = AnchorPresets.TopRight; removeButton.Button.AnchorPreset = AnchorPresets.TopRight;
@@ -661,7 +661,7 @@ namespace FlaxEditor.CustomEditors.Editors
Resize(Count - 1); Resize(Count - 1);
}; };
var addButton = panel.Button("+", "Add a new item."); var addButton = panel.Button("+", "Add a new item");
addButton.Button.Size = new Float2(16, 16); addButton.Button.Size = new Float2(16, 16);
addButton.Button.Enabled = (!NotNullItems || size > 0) && size < _maxCount; addButton.Button.Enabled = (!NotNullItems || size > 0) && size < _maxCount;
addButton.Button.AnchorPreset = AnchorPresets.TopRight; addButton.Button.AnchorPreset = AnchorPresets.TopRight;

View File

@@ -321,11 +321,11 @@ namespace FlaxEditor.CustomEditors.Editors
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14); var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
// Deselect // Deselect
if (_value != null && button1Rect.Contains(location)) if (_value != null && button1Rect.Contains(ref location))
Value = null; Value = null;
// Picker dropdown menu // Picker dropdown menu
if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(location)) if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(ref location))
{ {
ShowDropDownMenu(); ShowDropDownMenu();
return true; return true;

View File

@@ -247,7 +247,7 @@ namespace FlaxEditor.CustomEditors.Editors
/// <returns>The items.</returns> /// <returns>The items.</returns>
protected virtual List<ItemInfo> GetItemsForType(ScriptType type) protected virtual List<ItemInfo> GetItemsForType(ScriptType type)
{ {
return GetItemsForType(type, type.IsClass, true, true); return GetItemsForType(type, type.IsClass, true);
} }
/// <summary> /// <summary>
@@ -273,14 +273,10 @@ namespace FlaxEditor.CustomEditors.Editors
var attributes = p.GetAttributes(true); var attributes = p.GetAttributes(true);
var showInEditor = attributes.Any(x => x is ShowInEditorAttribute); var showInEditor = attributes.Any(x => x is ShowInEditorAttribute);
// Skip properties without getter // Skip properties without getter or setter
if (!p.HasGet || (!p.HasSet && !showInEditor && !usePropertiesWithoutSetter)) if (!p.HasGet || (!p.HasSet && !showInEditor && !usePropertiesWithoutSetter))
continue; continue;
// Skip getter-only properties declared in built-in types
if (!p.HasSet && usePropertiesWithoutSetter && p.Type.DeclaringType.Assembly == typeof(Editor).Assembly)
continue;
// Skip hidden fields, handle special attributes // Skip hidden fields, handle special attributes
if ((!p.IsPublic && !showInEditor) || attributes.Any(x => x is HideInEditorAttribute)) if ((!p.IsPublic && !showInEditor) || attributes.Any(x => x is HideInEditorAttribute))
continue; continue;

View File

@@ -104,7 +104,7 @@ namespace FlaxEditor.CustomEditors.Editors
public event Action<TypePickerControl> TypePickerValueChanged; public event Action<TypePickerControl> TypePickerValueChanged;
/// <summary> /// <summary>
/// The custom callback for types validation. Can be used to implement a rule for types to pick. /// The custom callback for types validation. Cane be used to implement a rule for types to pick.
/// </summary> /// </summary>
public Func<ScriptType, bool> CheckValid; public Func<ScriptType, bool> CheckValid;
@@ -219,11 +219,11 @@ namespace FlaxEditor.CustomEditors.Editors
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14); var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
// Deselect // Deselect
if (_value && button1Rect.Contains(location) && _type == ScriptType.Null) if (_value && button1Rect.Contains(ref location) && _type == ScriptType.Null)
Value = ScriptType.Null; Value = ScriptType.Null;
// Picker dropdown menu // Picker dropdown menu
if ((isSelected && _type == ScriptType.Null ? button2Rect : button1Rect).Contains(location)) if ((isSelected && _type == ScriptType.Null ? button2Rect : button1Rect).Contains(ref location))
ShowDropDownMenu(); ShowDropDownMenu();
return base.OnMouseUp(location, button); return base.OnMouseUp(location, button);
@@ -353,13 +353,7 @@ namespace FlaxEditor.CustomEditors.Editors
} }
if (!string.IsNullOrEmpty(typeReference.CheckMethod)) if (!string.IsNullOrEmpty(typeReference.CheckMethod))
{ {
var parentEditor = ParentEditor; var parentType = ParentEditor.Values[0].GetType();
// Find actual parent editor if parent editor is collection editor
while (parentEditor.GetType().IsAssignableTo(typeof(CollectionEditor)))
parentEditor = parentEditor.ParentEditor;
var parentType = parentEditor.Values[0].GetType();
var method = parentType.GetMethod(typeReference.CheckMethod, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); var method = parentType.GetMethod(typeReference.CheckMethod, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (method != null) if (method != null)
{ {

View File

@@ -526,23 +526,6 @@ int32 Editor::LoadProduct()
return 12; return 12;
} }
// Get the last opened project path
String localCachePath;
FileSystem::GetSpecialFolderPath(SpecialFolder::AppData, localCachePath);
String editorConfigPath = localCachePath / TEXT("Flax");
String lastProjectSettingPath = editorConfigPath / TEXT("LastProject.txt");
if (!FileSystem::DirectoryExists(editorConfigPath))
FileSystem::CreateDirectory(editorConfigPath);
String lastProjectPath;
if (FileSystem::FileExists(lastProjectSettingPath))
File::ReadAllText(lastProjectSettingPath, lastProjectPath);
if (!FileSystem::DirectoryExists(lastProjectPath))
lastProjectPath = String::Empty;
// Try to open the last project when requested
if (projectPath.IsEmpty() && CommandLine::Options.LastProject.IsTrue() && !lastProjectPath.IsEmpty())
projectPath = lastProjectPath;
// Missing project case // Missing project case
if (projectPath.IsEmpty()) if (projectPath.IsEmpty())
{ {
@@ -558,7 +541,7 @@ int32 Editor::LoadProduct()
Array<String> files; Array<String> files;
if (FileSystem::ShowOpenFileDialog( if (FileSystem::ShowOpenFileDialog(
nullptr, nullptr,
lastProjectPath, StringView::Empty,
TEXT("Project files (*.flaxproj)\0*.flaxproj\0All files (*.*)\0*.*\0"), TEXT("Project files (*.flaxproj)\0*.flaxproj\0All files (*.*)\0*.*\0"),
false, false,
TEXT("Select project to open in Editor"), TEXT("Select project to open in Editor"),
@@ -642,10 +625,6 @@ int32 Editor::LoadProduct()
} }
} }
// Update the last opened project path
if (lastProjectPath.Compare(Project->ProjectFolderPath) != 0)
File::WriteAllText(lastProjectSettingPath, Project->ProjectFolderPath, Encoding::UTF8);
return 0; return 0;
} }

View File

@@ -1056,7 +1056,7 @@ namespace FlaxEditor
if (actor) if (actor)
{ {
Internal_GetEditorBoxWithChildren(FlaxEngine.Object.GetUnmanagedPtr(actor), out var box); Internal_GetEditorBoxWithChildren(FlaxEngine.Object.GetUnmanagedPtr(actor), out var box);
BoundingSphere.FromBox(box, out sphere); BoundingSphere.FromBox(ref box, out sphere);
if (sphere == BoundingSphere.Empty) if (sphere == BoundingSphere.Empty)
sphere = new BoundingSphere(actor.Position, sphere.Radius); sphere = new BoundingSphere(actor.Position, sphere.Radius);
sphere.Radius = Math.Max(sphere.Radius, 15.0f); sphere.Radius = Math.Max(sphere.Radius, 15.0f);
@@ -1390,7 +1390,6 @@ namespace FlaxEditor
public void BuildAllMeshesSDF() public void BuildAllMeshesSDF()
{ {
var models = new List<Model>(); var models = new List<Model>();
var forceRebuild = Input.GetKey(KeyboardKeys.F);
Scene.ExecuteOnGraph(node => Scene.ExecuteOnGraph(node =>
{ {
if (node is StaticModelNode staticModelNode && staticModelNode.Actor is StaticModel staticModel) if (node is StaticModelNode staticModelNode && staticModelNode.Actor is StaticModel staticModel)
@@ -1400,7 +1399,7 @@ namespace FlaxEditor
model != null && model != null &&
!models.Contains(model) && !models.Contains(model) &&
!model.IsVirtual && !model.IsVirtual &&
(forceRebuild || model.SDF.Texture == null)) model.SDF.Texture == null)
{ {
models.Add(model); models.Add(model);
} }
@@ -1413,17 +1412,7 @@ namespace FlaxEditor
{ {
var model = models[i]; var model = models[i];
Log($"[{i}/{models.Count}] Generating SDF for {model}"); Log($"[{i}/{models.Count}] Generating SDF for {model}");
float resolutionScale = 1.0f, backfacesThreshold = 0.6f; if (!model.GenerateSDF())
int lodIndex = 6;
bool useGPU = true;
var sdf = model.SDF;
if (sdf.Texture != null)
{
// Preserve options set on this model
resolutionScale = sdf.ResolutionScale;
lodIndex = sdf.LOD;
}
if (!model.GenerateSDF(resolutionScale, lodIndex, true, backfacesThreshold, useGPU))
model.Save(); model.Save();
} }
}); });
@@ -1598,7 +1587,7 @@ namespace FlaxEditor
if (dockedTo != null && dockedTo.SelectedTab != gameWin && dockedTo.SelectedTab != null) if (dockedTo != null && dockedTo.SelectedTab != gameWin && dockedTo.SelectedTab != null)
result = dockedTo.SelectedTab.Size; result = dockedTo.SelectedTab.Size;
else else
result = gameWin.Viewport.ContentSize; result = gameWin.Viewport.Size;
result *= root.DpiScale; result *= root.DpiScale;
result = Float2.Round(result); result = Float2.Round(result);

View File

@@ -96,7 +96,7 @@ namespace FlaxEditor.GUI
private void DoDrag() private void DoDrag()
{ {
// Do the drag drop operation if has selected element // Do the drag drop operation if has selected element
if (new Rectangle(Float2.Zero, Size).Contains(_mouseDownPos)) if (new Rectangle(Float2.Zero, Size).Contains(ref _mouseDownPos))
{ {
if (Validator.SelectedAsset != null) if (Validator.SelectedAsset != null)
DoDragDrop(DragAssets.GetDragData(Validator.SelectedAsset)); DoDragDrop(DragAssets.GetDragData(Validator.SelectedAsset));

View File

@@ -1,10 +1,7 @@
#if PLATFORM_WINDOWS || PLATFORM_SDL #if PLATFORM_WINDOWS
#define USE_IS_FOREGROUND #define USE_IS_FOREGROUND
#else #else
#endif #endif
#if PLATFORM_SDL
#define USE_SDL_WORKAROUNDS
#endif
// Copyright (c) Wojciech Figat. All rights reserved. // Copyright (c) Wojciech Figat. All rights reserved.
using System.Collections.Generic; using System.Collections.Generic;
@@ -125,7 +122,7 @@ namespace FlaxEditor.GUI.ContextMenu
} }
/// <summary> /// <summary>
/// Shows the empty menu popup on a screen. /// Shows the empty menu popup o na screen.
/// </summary> /// </summary>
/// <param name="control">The target control.</param> /// <param name="control">The target control.</param>
/// <param name="area">The target control area to cover.</param> /// <param name="area">The target control area to cover.</param>
@@ -260,9 +257,7 @@ namespace FlaxEditor.GUI.ContextMenu
desc.AllowMaximize = false; desc.AllowMaximize = false;
desc.AllowDragAndDrop = false; desc.AllowDragAndDrop = false;
desc.IsTopmost = true; desc.IsTopmost = true;
desc.Type = WindowType.Popup; desc.IsRegularWindow = false;
desc.Parent = parentWin.Window;
desc.Title = "ContextMenu";
desc.HasSizingFrame = false; desc.HasSizingFrame = false;
OnWindowCreating(ref desc); OnWindowCreating(ref desc);
_window = Platform.CreateWindow(ref desc); _window = Platform.CreateWindow(ref desc);
@@ -271,12 +266,6 @@ namespace FlaxEditor.GUI.ContextMenu
_window.GotFocus += OnWindowGotFocus; _window.GotFocus += OnWindowGotFocus;
_window.LostFocus += OnWindowLostFocus; _window.LostFocus += OnWindowLostFocus;
} }
#if USE_IS_FOREGROUND && USE_SDL_WORKAROUNDS
// The focus between popup and parent windows doesn't change, force hide the popup when clicked on parent
parentWin.Window.MouseDown += OnWindowMouseDown;
_window.Closed += () => parentWin.Window.MouseDown -= OnWindowMouseDown;
#endif
// Attach to the window // Attach to the window
_parentCM = parent as ContextMenuBase; _parentCM = parent as ContextMenuBase;
@@ -452,17 +441,6 @@ namespace FlaxEditor.GUI.ContextMenu
} }
} }
#if USE_SDL_WORKAROUNDS
private void OnWindowGotFocus()
{
}
private void OnWindowMouseDown(ref Float2 mousePosition, MouseButton button, ref bool handled)
{
// The user clicked outside the popup window
Hide();
}
#else
private void OnWindowGotFocus() private void OnWindowGotFocus()
{ {
var child = _childCM; var child = _childCM;
@@ -476,7 +454,6 @@ namespace FlaxEditor.GUI.ContextMenu
}); });
} }
} }
#endif
private void OnWindowLostFocus() private void OnWindowLostFocus()
{ {
@@ -575,12 +552,7 @@ namespace FlaxEditor.GUI.ContextMenu
// Let root context menu to check if none of the popup windows // Let root context menu to check if none of the popup windows
if (_parentCM == null && UseVisibilityControl && !IsForeground) if (_parentCM == null && UseVisibilityControl && !IsForeground)
{ {
#if USE_SDL_WORKAROUNDS
if (!IsMouseOver)
Hide();
#else
Hide(); Hide();
#endif
} }
} }
#endif #endif

View File

@@ -62,7 +62,7 @@ namespace FlaxEditor.GUI
for (int i = 0; i < children.Count; i++) for (int i = 0; i < children.Count; i++)
{ {
if (children[i] is KeyframePoint p) if (children[i] is KeyframePoint p)
p.IsSelected = p.Bounds.Intersects(selectionRect); p.IsSelected = p.Bounds.Intersects(ref selectionRect);
} }
_editor.UpdateTangents(); _editor.UpdateTangents();
} }
@@ -85,7 +85,7 @@ namespace FlaxEditor.GUI
internal void OnMove(Float2 location) internal void OnMove(Float2 location)
{ {
// Skip updating keyframes until move actual starts to be meaningful // Skip updating keyframes until move actual starts to be meaningful
if (Float2.Distance(_movingSelectionStartPosLock, location) < 1.5f) if (Float2.Distance(ref _movingSelectionStartPosLock, ref location) < 1.5f)
return; return;
_movingSelectionStartPosLock = Float2.Minimum; _movingSelectionStartPosLock = Float2.Minimum;

View File

@@ -689,8 +689,8 @@ namespace FlaxEditor.GUI
if (selectedOnly && !point.IsSelected) if (selectedOnly && !point.IsSelected)
continue; continue;
var pos = point.Point; var pos = point.Point;
Float2.Min(posMin, pos, out posMin); Float2.Min(ref posMin, ref pos, out posMin);
Float2.Max(posMax, pos, out posMax); Float2.Max(ref posMax, ref pos, out posMax);
} }
// Apply margin around the area // Apply margin around the area
@@ -703,16 +703,16 @@ namespace FlaxEditor.GUI
PointFromKeyframesToContents(ref posMin, ref viewRect); PointFromKeyframesToContents(ref posMin, ref viewRect);
PointFromKeyframesToContents(ref posMax, ref viewRect); PointFromKeyframesToContents(ref posMax, ref viewRect);
var tmp = posMin; var tmp = posMin;
Float2.Min(posMin, posMax, out posMin); Float2.Min(ref posMin, ref posMax, out posMin);
Float2.Max(posMax, tmp, out posMax); Float2.Max(ref posMax, ref tmp, out posMax);
var contentsSize = posMax - posMin; var contentsSize = posMax - posMin;
// Convert from Contents to Main Panel // Convert from Contents to Main Panel
posMin = _contents.PointToParent(posMin); posMin = _contents.PointToParent(posMin);
posMax = _contents.PointToParent(posMax); posMax = _contents.PointToParent(posMax);
tmp = posMin; tmp = posMin;
Float2.Min(posMin, posMax, out posMin); Float2.Min(ref posMin, ref posMax, out posMin);
Float2.Max(posMax, tmp, out posMax); Float2.Max(ref posMax, ref tmp, out posMax);
// Update zoom (leave unchanged when focusing a single point) // Update zoom (leave unchanged when focusing a single point)
var zoomMask = EnableZoom; var zoomMask = EnableZoom;
@@ -941,7 +941,7 @@ namespace FlaxEditor.GUI
{ {
SetupGrid(out var min, out var max, out var pixelRange); SetupGrid(out var min, out var max, out var pixelRange);
Render2D.PushClip(viewRect); Render2D.PushClip(ref viewRect);
if ((ShowAxes & UseMode.Vertical) == UseMode.Vertical) if ((ShowAxes & UseMode.Vertical) == UseMode.Vertical)
DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X); DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X);
@@ -954,7 +954,7 @@ namespace FlaxEditor.GUI
// Draw curve // Draw curve
if (!_showCollapsed) if (!_showCollapsed)
{ {
Render2D.PushClip(rect); Render2D.PushClip(ref rect);
DrawCurve(ref viewRect); DrawCurve(ref viewRect);
Render2D.PopClip(); Render2D.PopClip();
} }

View File

@@ -326,11 +326,8 @@ namespace FlaxEditor.GUI.Dialogs
// Update eye dropper tool // Update eye dropper tool
if (_activeEyedropper) if (_activeEyedropper)
{ {
// Try reading the color under the cursor in realtime if supported by the platform
Float2 mousePosition = Platform.MousePosition; Float2 mousePosition = Platform.MousePosition;
Color color = ScreenUtilities.GetColorAt(mousePosition); SelectedColor = ScreenUtilities.GetColorAt(mousePosition);
if (color != Color.Transparent)
SelectedColor = color;
} }
} }

View File

@@ -0,0 +1,545 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.GUI.Docking
{
/// <summary>
/// Helper class used to handle docking windows dragging and docking.
/// </summary>
public class DockHintWindow
{
private FloatWindowDockPanel _toMove;
private Float2 _dragOffset;
private Float2 _defaultWindowSize;
private Rectangle _rectDock;
private Rectangle _rectWindow;
private Float2 _mouse;
private DockState _toSet;
private DockPanel _toDock;
private bool _lateDragOffsetUpdate;
private Rectangle _rLeft, _rRight, _rBottom, _rUpper, _rCenter;
private DockHintWindow(FloatWindowDockPanel toMove)
{
_toMove = toMove;
_toSet = DockState.Float;
var window = toMove.Window.Window;
// Remove focus from drag target
_toMove.Focus();
_toMove.Defocus();
// Focus window
window.Focus();
// Check if window is maximized and restore window.
if (window.IsMaximized)
{
// Restore window and set position to mouse.
var mousePos = window.MousePosition;
var previousSize = window.Size;
window.Restore();
window.Position = Platform.MousePosition - mousePos * window.Size / previousSize;
}
// Calculate dragging offset and move window to the destination position
var mouseScreenPosition = Platform.MousePosition;
// If the _toMove window was not focused when initializing this window, the result vector only contains zeros
// and to prevent a failure, we need to perform an update for the drag offset at later time which will be done in the OnMouseMove event handler.
if (mouseScreenPosition != Float2.Zero)
CalculateDragOffset(mouseScreenPosition);
else
_lateDragOffsetUpdate = true;
// Get initial size
_defaultWindowSize = window.Size;
// Init proxy window
Proxy.Init(ref _defaultWindowSize);
// Bind events
Proxy.Window.MouseUp += OnMouseUp;
Proxy.Window.MouseMove += OnMouseMove;
Proxy.Window.LostFocus += OnLostFocus;
// Start tracking mouse
Proxy.Window.StartTrackingMouse(false);
// Update window GUI
Proxy.Window.GUI.PerformLayout();
// Update rectangles
UpdateRects();
// Hide base window
window.Hide();
// Enable hit window presentation
Proxy.Window.RenderingEnabled = true;
Proxy.Window.Show();
Proxy.Window.Focus();
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
public void Dispose()
{
// End tracking mouse
Proxy.Window.EndTrackingMouse();
// Disable rendering
Proxy.Window.RenderingEnabled = false;
// Unbind events
Proxy.Window.MouseUp -= OnMouseUp;
Proxy.Window.MouseMove -= OnMouseMove;
Proxy.Window.LostFocus -= OnLostFocus;
// Hide the proxy
Proxy.Hide();
if (_toMove == null)
return;
// Check if window won't be docked
if (_toSet == DockState.Float)
{
var window = _toMove.Window?.Window;
if (window == null)
return;
var mouse = Platform.MousePosition;
// Move base window
window.Position = mouse - _dragOffset;
// Show base window
window.Show();
}
else
{
bool hasNoChildPanels = _toMove.ChildPanelsCount == 0;
// Check if window has only single tab
if (hasNoChildPanels && _toMove.TabsCount == 1)
{
// Dock window
_toMove.GetTab(0).Show(_toSet, _toDock);
}
// Check if dock as tab and has no child panels
else if (hasNoChildPanels && _toSet == DockState.DockFill)
{
// Dock all tabs
while (_toMove.TabsCount > 0)
{
_toMove.GetTab(0).Show(DockState.DockFill, _toDock);
}
}
else
{
var selectedTab = _toMove.SelectedTab;
// Dock the first tab into the target location
var firstTab = _toMove.GetTab(0);
firstTab.Show(_toSet, _toDock);
// Dock rest of the tabs
while (_toMove.TabsCount > 0)
{
_toMove.GetTab(0).Show(DockState.DockFill, firstTab);
}
// Keep selected tab being selected
selectedTab?.SelectTab();
}
// Focus target window
_toDock.Root.Focus();
}
_toMove = null;
}
/// <summary>
/// Creates the new dragging hit window.
/// </summary>
/// <param name="toMove">Floating dock panel to move.</param>
/// <returns>The dock hint window object.</returns>
public static DockHintWindow Create(FloatWindowDockPanel toMove)
{
if (toMove == null)
throw new ArgumentNullException();
return new DockHintWindow(toMove);
}
/// <summary>
/// Creates the new dragging hit window.
/// </summary>
/// <param name="toMove">Dock window to move.</param>
/// <returns>The dock hint window object.</returns>
public static DockHintWindow Create(DockWindow toMove)
{
if (toMove == null)
throw new ArgumentNullException();
// Show floating
toMove.ShowFloating();
// Move window to the mouse position (with some offset for caption bar)
var window = (WindowRootControl)toMove.Root;
var mouse = Platform.MousePosition;
window.Window.Position = mouse - new Float2(8, 8);
// Get floating panel
var floatingPanelToMove = window.GetChild(0) as FloatWindowDockPanel;
return new DockHintWindow(floatingPanelToMove);
}
/// <summary>
/// Calculates window rectangle in the dock window.
/// </summary>
/// <param name="state">Window dock state.</param>
/// <param name="rect">Dock panel rectangle.</param>
/// <returns>Calculated window rectangle.</returns>
public static Rectangle CalculateDockRect(DockState state, ref Rectangle rect)
{
Rectangle result = rect;
switch (state)
{
case DockState.DockFill:
result.Location.Y += Editor.Instance.Options.Options.Interface.TabHeight;
result.Size.Y -= Editor.Instance.Options.Options.Interface.TabHeight;
break;
case DockState.DockTop:
result.Size.Y *= DockPanel.DefaultSplitterValue;
break;
case DockState.DockLeft:
result.Size.X *= DockPanel.DefaultSplitterValue;
break;
case DockState.DockBottom:
result.Location.Y += result.Size.Y * (1 - DockPanel.DefaultSplitterValue);
result.Size.Y *= DockPanel.DefaultSplitterValue;
break;
case DockState.DockRight:
result.Location.X += result.Size.X * (1 - DockPanel.DefaultSplitterValue);
result.Size.X *= DockPanel.DefaultSplitterValue;
break;
}
return result;
}
private void CalculateDragOffset(Float2 mouseScreenPosition)
{
var baseWinPos = _toMove.Window.Window.Position;
_dragOffset = mouseScreenPosition - baseWinPos;
}
private void UpdateRects()
{
// Cache mouse position
_mouse = Platform.MousePosition;
// Check intersection with any dock panel
var uiMouse = _mouse;
_toDock = _toMove.MasterPanel.HitTest(ref uiMouse, _toMove);
// Check dock state to use
bool showProxyHints = _toDock != null;
bool showBorderHints = showProxyHints;
bool showCenterHint = showProxyHints;
if (showProxyHints)
{
// If moved window has not only tabs but also child panels disable docking as tab
if (_toMove.ChildPanelsCount > 0)
showCenterHint = false;
// Disable docking windows with one or more dock panels inside
if (_toMove.ChildPanelsCount > 0)
showBorderHints = false;
// Get dock area
_rectDock = _toDock.DockAreaBounds;
// Cache dock rectangles
var size = _rectDock.Size;
var offset = _rectDock.Location;
var borderMargin = 4.0f;
var hintWindowsSize = Proxy.HintWindowsSize * Platform.DpiScale;
var hintWindowsSize2 = hintWindowsSize * 0.5f;
var centerX = size.X * 0.5f;
var centerY = size.Y * 0.5f;
_rUpper = new Rectangle(centerX - hintWindowsSize2, borderMargin, hintWindowsSize, hintWindowsSize) + offset;
_rBottom = new Rectangle(centerX - hintWindowsSize2, size.Y - hintWindowsSize - borderMargin, hintWindowsSize, hintWindowsSize) + offset;
_rLeft = new Rectangle(borderMargin, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
_rRight = new Rectangle(size.X - hintWindowsSize - borderMargin, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
_rCenter = new Rectangle(centerX - hintWindowsSize2, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
// Hit test
DockState toSet = DockState.Float;
if (showBorderHints)
{
if (_rUpper.Contains(_mouse))
toSet = DockState.DockTop;
else if (_rBottom.Contains(_mouse))
toSet = DockState.DockBottom;
else if (_rLeft.Contains(_mouse))
toSet = DockState.DockLeft;
else if (_rRight.Contains(_mouse))
toSet = DockState.DockRight;
}
if (showCenterHint && _rCenter.Contains(_mouse))
toSet = DockState.DockFill;
_toSet = toSet;
// Show proxy hint windows
Proxy.Down.Position = _rBottom.Location;
Proxy.Left.Position = _rLeft.Location;
Proxy.Right.Position = _rRight.Location;
Proxy.Up.Position = _rUpper.Location;
Proxy.Center.Position = _rCenter.Location;
}
else
{
_toSet = DockState.Float;
}
// Update proxy hint windows visibility
Proxy.Down.IsVisible = showProxyHints & showBorderHints;
Proxy.Left.IsVisible = showProxyHints & showBorderHints;
Proxy.Right.IsVisible = showProxyHints & showBorderHints;
Proxy.Up.IsVisible = showProxyHints & showBorderHints;
Proxy.Center.IsVisible = showProxyHints & showCenterHint;
// Calculate proxy/dock/window rectangles
if (_toDock == null)
{
// Floating window over nothing
_rectWindow = new Rectangle(_mouse - _dragOffset, _defaultWindowSize);
}
else
{
if (_toSet == DockState.Float)
{
// Floating window over dock panel
_rectWindow = new Rectangle(_mouse - _dragOffset, _defaultWindowSize);
}
else
{
// Use only part of the dock panel to show hint
_rectWindow = CalculateDockRect(_toSet, ref _rectDock);
}
}
// Update proxy window
Proxy.Window.ClientBounds = _rectWindow;
}
private void OnMouseUp(ref Float2 location, MouseButton button, ref bool handled)
{
if (button == MouseButton.Left)
{
Dispose();
}
}
private void OnMouseMove(ref Float2 mousePos)
{
// Recalculate the drag offset because the current mouse screen position was invalid when we initialized the window
if (_lateDragOffsetUpdate)
{
// Calculate dragging offset and move window to the destination position
CalculateDragOffset(mousePos);
// Reset state
_lateDragOffsetUpdate = false;
}
UpdateRects();
}
private void OnLostFocus()
{
Dispose();
}
/// <summary>
/// Contains helper proxy windows shared across docking panels. They are used to visualize docking window locations.
/// </summary>
public static class Proxy
{
/// <summary>
/// The drag proxy window.
/// </summary>
public static Window Window;
/// <summary>
/// The left hint proxy window.
/// </summary>
public static Window Left;
/// <summary>
/// The right hint proxy window.
/// </summary>
public static Window Right;
/// <summary>
/// The up hint proxy window.
/// </summary>
public static Window Up;
/// <summary>
/// The down hint proxy window.
/// </summary>
public static Window Down;
/// <summary>
/// The center hint proxy window.
/// </summary>
public static Window Center;
/// <summary>
/// The hint windows size.
/// </summary>
public const float HintWindowsSize = 32.0f;
/// <summary>
/// Initializes the hit proxy windows. Those windows are used to indicate drag target areas (left, right, top, bottom, etc.).
/// </summary>
public static void InitHitProxy()
{
CreateProxy(ref Left, "DockHint.Left");
CreateProxy(ref Right, "DockHint.Right");
CreateProxy(ref Up, "DockHint.Up");
CreateProxy(ref Down, "DockHint.Down");
CreateProxy(ref Center, "DockHint.Center");
}
/// <summary>
/// Initializes the hint window.
/// </summary>
/// <param name="initSize">Initial size of the proxy window.</param>
public static void Init(ref Float2 initSize)
{
if (Window == null)
{
var settings = CreateWindowSettings.Default;
settings.Title = "DockHint.Window";
settings.Size = initSize;
settings.AllowInput = true;
settings.AllowMaximize = false;
settings.AllowMinimize = false;
settings.HasBorder = false;
settings.HasSizingFrame = false;
settings.IsRegularWindow = false;
settings.SupportsTransparency = true;
settings.ShowInTaskbar = false;
settings.ShowAfterFirstPaint = false;
settings.IsTopmost = true;
Window = Platform.CreateWindow(ref settings);
Window.Opacity = 0.6f;
Window.GUI.BackgroundColor = Style.Current.Selection;
Window.GUI.AddChild<DragVisuals>();
}
else
{
// Resize proxy
Window.ClientSize = initSize;
}
InitHitProxy();
}
private sealed class DragVisuals : Control
{
public DragVisuals()
{
AnchorPreset = AnchorPresets.StretchAll;
Offsets = Margin.Zero;
}
public override void Draw()
{
Render2D.DrawRectangle(new Rectangle(Float2.Zero, Size), Style.Current.SelectionBorder);
}
}
private static void CreateProxy(ref Window win, string name)
{
if (win != null)
return;
var settings = CreateWindowSettings.Default;
settings.Title = name;
settings.Size = new Float2(HintWindowsSize * Platform.DpiScale);
settings.AllowInput = false;
settings.AllowMaximize = false;
settings.AllowMinimize = false;
settings.HasBorder = false;
settings.HasSizingFrame = false;
settings.IsRegularWindow = false;
settings.SupportsTransparency = true;
settings.ShowInTaskbar = false;
settings.ActivateWhenFirstShown = false;
settings.IsTopmost = true;
settings.ShowAfterFirstPaint = false;
win = Platform.CreateWindow(ref settings);
win.Opacity = 0.6f;
win.GUI.BackgroundColor = Style.Current.Selection;
win.GUI.AddChild<DragVisuals>();
}
/// <summary>
/// Hides proxy windows.
/// </summary>
public static void Hide()
{
HideProxy(ref Window);
HideProxy(ref Left);
HideProxy(ref Right);
HideProxy(ref Up);
HideProxy(ref Down);
HideProxy(ref Center);
}
private static void HideProxy(ref Window win)
{
if (win)
{
win.Hide();
}
}
/// <summary>
/// Releases proxy data and windows.
/// </summary>
public static void Dispose()
{
DisposeProxy(ref Window);
DisposeProxy(ref Left);
DisposeProxy(ref Right);
DisposeProxy(ref Up);
DisposeProxy(ref Down);
DisposeProxy(ref Center);
}
private static void DisposeProxy(ref Window win)
{
if (win)
{
win.Close(ClosingReason.User);
win = null;
}
}
}
}
}

View File

@@ -19,7 +19,11 @@ namespace FlaxEditor.GUI.Docking
private float _tabHeight = Editor.Instance.Options.Options.Interface.TabHeight; private float _tabHeight = Editor.Instance.Options.Options.Interface.TabHeight;
private bool _useMinimumTabWidth = Editor.Instance.Options.Options.Interface.UseMinimumTabWidth; private bool _useMinimumTabWidth = Editor.Instance.Options.Options.Interface.UseMinimumTabWidth;
private float _minimumTabWidth = Editor.Instance.Options.Options.Interface.MinimumTabWidth; private float _minimumTabWidth = Editor.Instance.Options.Options.Interface.MinimumTabWidth;
private readonly bool _hideTabForSingleTab = Utilities.Utils.HideSingleTabWindowTabBars(); #if PLATFORM_WINDOWS
private readonly bool _hideTabForSingleTab = Editor.Instance.Options.Options.Interface.HideSingleTabWindowTabBars;
#else
private readonly bool _hideTabForSingleTab = false;
#endif
/// <summary> /// <summary>
/// The is mouse down flag (left button). /// The is mouse down flag (left button).
@@ -50,11 +54,6 @@ namespace FlaxEditor.GUI.Docking
/// The mouse position. /// The mouse position.
/// </summary> /// </summary>
public Float2 MousePosition = Float2.Minimum; public Float2 MousePosition = Float2.Minimum;
/// <summary>
/// The mouse position.
/// </summary>
public Float2 MouseStartPosition = Float2.Minimum;
/// <summary> /// <summary>
/// The start drag asynchronous window. /// The start drag asynchronous window.
@@ -197,7 +196,7 @@ namespace FlaxEditor.GUI.Docking
if (_panel.ChildPanelsCount == 0 && _panel.TabsCount == 1 && _panel.IsFloating) if (_panel.ChildPanelsCount == 0 && _panel.TabsCount == 1 && _panel.IsFloating)
{ {
// Create docking hint window but in an async manner // Create docking hint window but in an async manner
WindowDragHelper.StartDragging(_panel as FloatWindowDockPanel); DockHintWindow.Create(_panel as FloatWindowDockPanel);
} }
else else
{ {
@@ -208,7 +207,7 @@ namespace FlaxEditor.GUI.Docking
_panel.SelectTab(index - 1); _panel.SelectTab(index - 1);
// Create docking hint window // Create docking hint window
WindowDragHelper.StartDragging(win, _panel.RootWindow.Window); DockHintWindow.Create(win);
} }
} }
} }
@@ -394,7 +393,6 @@ namespace FlaxEditor.GUI.Docking
if (IsSingleFloatingWindow) if (IsSingleFloatingWindow)
return base.OnMouseDown(location, button); return base.OnMouseDown(location, button);
MouseDownWindow = GetTabAtPos(location, out IsMouseDownOverCross); MouseDownWindow = GetTabAtPos(location, out IsMouseDownOverCross);
MouseStartPosition = location;
// Check buttons // Check buttons
if (button == MouseButton.Left) if (button == MouseButton.Left)
@@ -481,20 +479,6 @@ namespace FlaxEditor.GUI.Docking
StartDrag(MouseDownWindow); StartDrag(MouseDownWindow);
MouseDownWindow = null; MouseDownWindow = null;
} }
// Check if single tab is tried to be moved
else if (MouseDownWindow != null && _panel.TabsCount <= 1)
{
if ((MousePosition - MouseStartPosition).Length > 3)
{
// Clear flag
IsMouseLeftButtonDown = false;
// Check tab under the mouse
if (!IsMouseDownOverCross && MouseDownWindow != null)
StartDrag(MouseDownWindow);
MouseDownWindow = null;
}
}
// Check if has more than one tab to change order // Check if has more than one tab to change order
else if (MouseDownWindow != null && _panel.TabsCount > 1) else if (MouseDownWindow != null && _panel.TabsCount > 1)
{ {

View File

@@ -182,25 +182,6 @@ namespace FlaxEditor.GUI.Docking
/// <param name="size">Window size, set <see cref="Float2.Zero"/> to use default.</param> /// <param name="size">Window size, set <see cref="Float2.Zero"/> to use default.</param>
/// <param name="position">Window location.</param> /// <param name="position">Window location.</param>
public void ShowFloating(Float2 location, Float2 size, WindowStartPosition position = WindowStartPosition.CenterParent) public void ShowFloating(Float2 location, Float2 size, WindowStartPosition position = WindowStartPosition.CenterParent)
{
CreateFloating(location, size, position, true);
}
/// <summary>
/// Creates the window in a floating state.
/// </summary>
public void CreateFloating()
{
CreateFloating(Float2.Zero, Float2.Zero);
}
/// <summary>
/// Creates the window in a floating state.
/// </summary>
/// <param name="location">Window location.</param>
/// <param name="size">Window size, set <see cref="Float2.Zero"/> to use default.</param>
/// <param name="position">Window location.</param>
/// <param name="showWindow">Window visibility.</param>
public void CreateFloating(Float2 location, Float2 size, WindowStartPosition position = WindowStartPosition.CenterParent, bool showWindow = false)
{ {
Undock(); Undock();
@@ -218,17 +199,14 @@ namespace FlaxEditor.GUI.Docking
windowGUI.UnlockChildrenRecursive(); windowGUI.UnlockChildrenRecursive();
windowGUI.PerformLayout(); windowGUI.PerformLayout();
if (showWindow) // Show
{ window.Show();
// Show window.BringToFront();
window.Show(); window.Focus();
window.BringToFront(); OnShow();
window.Focus();
OnShow();
// Perform layout again // Perform layout again
windowGUI.PerformLayout(); windowGUI.PerformLayout();
}
} }
/// <summary> /// <summary>

View File

@@ -11,42 +11,6 @@ namespace FlaxEditor.GUI.Docking
/// <seealso cref="DockPanel" /> /// <seealso cref="DockPanel" />
public class FloatWindowDockPanel : DockPanel public class FloatWindowDockPanel : DockPanel
{ {
private class FloatWindowDecorations : WindowDecorations
{
private FloatWindowDockPanel _panel;
public FloatWindowDecorations(FloatWindowDockPanel panel)
: base(panel.RootWindow)
{
_panel = panel;
}
/// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button)
{
if (Title.Bounds.Contains(location) && button == MouseButton.Left)
{
_panel.BeginDrag();
return true;
}
return base.OnMouseDown(location, button);
}
#if !PLATFORM_WINDOWS
/// <inheritdoc />
protected override WindowHitCodes OnHitTest(ref Float2 mouse)
{
var hit = base.OnHitTest(ref mouse);
if (hit == WindowHitCodes.Caption)
{
// Override the system behaviour when interacting with the caption area
hit = WindowHitCodes.Client;
}
return hit;
}
#endif
}
private MasterDockPanel _masterPanel; private MasterDockPanel _masterPanel;
private WindowRootControl _window; private WindowRootControl _window;
@@ -76,26 +40,6 @@ namespace FlaxEditor.GUI.Docking
Parent = window; Parent = window;
_window.Window.Closing += OnClosing; _window.Window.Closing += OnClosing;
_window.Window.LeftButtonHit += OnLeftButtonHit; _window.Window.LeftButtonHit += OnLeftButtonHit;
if (Utilities.Utils.UseCustomWindowDecorations())
{
var decorations = Parent.AddChild(new FloatWindowDecorations(this));
decorations.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, false);
}
}
/// <inheritdoc />
protected override void PerformLayoutBeforeChildren()
{
base.PerformLayoutBeforeChildren();
var decorations = Parent.GetChild<FloatWindowDecorations>();
if (decorations != null)
{
// Apply offset for the title bar
foreach (var child in Children)
child.Bounds = child.Bounds with { Y = decorations.Height, Height = Parent.Height - decorations.Height };
}
} }
/// <summary> /// <summary>
@@ -108,7 +52,7 @@ namespace FlaxEditor.GUI.Docking
return; return;
// Create docking hint window // Create docking hint window
WindowDragHelper.StartDragging(this); DockHintWindow.Create(this);
} }
/// <summary> /// <summary>
@@ -127,28 +71,22 @@ namespace FlaxEditor.GUI.Docking
settings.Title = title; settings.Title = title;
settings.Size = size; settings.Size = size;
settings.Position = location; settings.Position = location;
settings.MinimumSize = new Float2(200, 150); settings.MinimumSize = new Float2(1);
settings.MaximumSize = Float2.Zero; // Unlimited size settings.MaximumSize = Float2.Zero; // Unlimited size
settings.Fullscreen = false; settings.Fullscreen = false;
settings.HasBorder = true; settings.HasBorder = true;
settings.SupportsTransparency = true; settings.SupportsTransparency = false;
settings.ActivateWhenFirstShown = true; settings.ActivateWhenFirstShown = true;
settings.AllowInput = true; settings.AllowInput = true;
settings.AllowMinimize = true; settings.AllowMinimize = true;
settings.AllowMaximize = true; settings.AllowMaximize = true;
settings.AllowDragAndDrop = true; settings.AllowDragAndDrop = true;
settings.IsTopmost = false; settings.IsTopmost = false;
settings.Type = WindowType.Regular; settings.IsRegularWindow = true;
settings.HasSizingFrame = true; settings.HasSizingFrame = true;
settings.ShowAfterFirstPaint = false; settings.ShowAfterFirstPaint = false;
settings.ShowInTaskbar = true; settings.ShowInTaskbar = true;
settings.StartPosition = startPosition; settings.StartPosition = startPosition;
if (Utilities.Utils.UseCustomWindowDecorations())
{
settings.HasBorder = false;
//settings.HasSizingFrame = false;
}
// Create window // Create window
return Platform.CreateWindow(ref settings); return Platform.CreateWindow(ref settings);

View File

@@ -81,6 +81,7 @@ namespace FlaxEditor.GUI.Docking
public DockPanel HitTest(ref Float2 position, FloatWindowDockPanel excluded) public DockPanel HitTest(ref Float2 position, FloatWindowDockPanel excluded)
{ {
// Check all floating windows // Check all floating windows
// TODO: gather windows order and take it into account when performing test
for (int i = 0; i < FloatingPanels.Count; i++) for (int i = 0; i < FloatingPanels.Count; i++)
{ {
var win = FloatingPanels[i]; var win = FloatingPanels[i];
@@ -93,44 +94,9 @@ namespace FlaxEditor.GUI.Docking
} }
// Base // Base
//if (!Root?.RootWindow.Window.IsFocused ?? false)
// return null;
return base.HitTest(ref position); return base.HitTest(ref position);
} }
/// <summary>
/// Performs hit test over dock panel.
/// </summary>
/// <param name="position">Window space position to test.</param>
/// <param name="excluded">Floating window to omit during searching (and all docked to that one).</param>
/// <param name="hitResults">Results of the hit test</param>
/// <returns>True if any dock panels were hit, otherwise false.</returns>
public bool HitTest(ref Float2 position, FloatWindowDockPanel excluded, out DockPanel[] hitResults)
{
// Check all floating windows
List<DockPanel> results = new(FloatingPanels.Count);
for (int i = 0; i < FloatingPanels.Count; i++)
{
var win = FloatingPanels[i];
if (win.Visible && win != excluded)
{
var result = win.HitTest(ref position);
if (result != null)
results.Add(result);
}
}
// Base
//if (!Root?.RootWindow.Window.IsFocused ?? false)
// return null;
var baseResult = base.HitTest(ref position);
if (baseResult != null)
results.Add(baseResult);
hitResults = results.ToArray();
return hitResults.Length > 0;
}
internal void LinkWindow(DockWindow window) internal void LinkWindow(DockWindow window)
{ {
// Add to the windows list // Add to the windows list

View File

@@ -1,458 +0,0 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.GUI.Docking
{
/// <summary>
/// Helper class used to handle docking windows dragging and docking.
/// </summary>
public class WindowDragHelper
{
private FloatWindowDockPanel _toMove;
private Float2 _dragOffset;
private Rectangle _rectDock;
private Float2 _mouse;
private DockState _toSet;
private DockPanel _toDock;
private Window _dragSourceWindow;
private Rectangle _rLeft, _rRight, _rBottom, _rUpper, _rCenter;
private Control _dockHintDown, _dockHintUp, _dockHintLeft, _dockHintRight, _dockHintCenter;
/// <summary>
/// The hint control size.
/// </summary>
public const float HintControlSize = 32.0f;
/// <summary>
/// The opacity of the dragged window when hint controls are shown.
/// </summary>
public const float DragWindowOpacity = 0.4f;
/// <summary>
/// Returns true if any windows are being dragged.
/// </summary>
public static bool IsDragActive { get; private set; }
private WindowDragHelper(FloatWindowDockPanel toMove, Window dragSourceWindow)
{
IsDragActive = true;
_toMove = toMove;
_toSet = DockState.Float;
var window = toMove.Window.Window;
// Bind events
FlaxEngine.Scripting.Update += OnUpdate;
window.MouseUp += OnMouseUp;
// Update rectangles
UpdateRects(Platform.MousePosition);
// Ensure the dragged window stays on top of every other window
window.IsAlwaysOnTop = true;
_dragSourceWindow = dragSourceWindow;
if (_dragSourceWindow != null) // Detaching a tab from existing window
{
_dragOffset = new Float2(window.Size.X / 2, 10.0f);
_dragSourceWindow.MouseUp += OnMouseUp; // The mouse up event is sent to the source window on Windows
// TODO: when detaching tab in floating window (not main window), the drag source window is still main window?
var dragSourceWindowWayland = toMove.MasterPanel?.RootWindow.Window ?? Editor.Instance.Windows.MainWindow;
window.DoDragDrop(window.Title, _dragOffset, dragSourceWindowWayland);
}
else
{
_dragOffset = window.MousePosition;
window.DoDragDrop(window.Title, _dragOffset, window);
}
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
public void Dispose()
{
IsDragActive = false;
var window = _toMove?.Window?.Window;
// Unbind events
FlaxEngine.Scripting.Update -= OnUpdate;
if (window != null)
window.MouseUp -= OnMouseUp;
if (_dragSourceWindow != null)
_dragSourceWindow.MouseUp -= OnMouseUp;
RemoveDockHints();
if (_toMove == null)
return;
if (window != null)
{
window.Opacity = 1.0f;
window.IsAlwaysOnTop = false;
window.BringToFront();
}
// Check if window won't be docked
if (_toSet == DockState.Float)
{
if (window == null)
return;
// Show base window
window.Show();
}
else
{
bool hasNoChildPanels = _toMove.ChildPanelsCount == 0;
// Check if window has only single tab
if (hasNoChildPanels && _toMove.TabsCount == 1)
{
// Dock window
_toMove.GetTab(0).Show(_toSet, _toDock);
}
// Check if dock as tab and has no child panels
else if (hasNoChildPanels && _toSet == DockState.DockFill)
{
// Dock all tabs
while (_toMove.TabsCount > 0)
{
_toMove.GetTab(0).Show(DockState.DockFill, _toDock);
}
}
else
{
var selectedTab = _toMove.SelectedTab;
// Dock the first tab into the target location
if (_toMove.TabsCount > 0)
{
var firstTab = _toMove.GetTab(0);
firstTab.Show(_toSet, _toDock);
// Dock rest of the tabs
while (_toMove.TabsCount > 0)
{
_toMove.GetTab(0).Show(DockState.DockFill, firstTab);
}
}
// Keep selected tab being selected
selectedTab?.SelectTab();
}
// Focus target window
_toDock.Root.Focus();
}
_toMove = null;
}
/// <summary>
/// Start dragging a floating dock panel.
/// </summary>
/// <param name="toMove">Floating dock panel to move.</param>
/// <returns>The window drag helper object.</returns>
public static WindowDragHelper StartDragging(FloatWindowDockPanel toMove)
{
if (toMove == null)
throw new ArgumentNullException();
return new WindowDragHelper(toMove, null);
}
/// <summary>
/// Start dragging a docked panel into a floating window.
/// </summary>
/// <param name="toMove">Dock window to move.</param>
/// <param name="dragSourceWindow">The window where dragging started from.</param>
/// <returns>The window drag helper object.</returns>
public static WindowDragHelper StartDragging(DockWindow toMove, Window dragSourceWindow)
{
if (toMove == null)
throw new ArgumentNullException();
// Create floating window
toMove.CreateFloating();
// Get floating panel
var window = (WindowRootControl)toMove.Root;
var floatingPanelToMove = window.GetChild(0) as FloatWindowDockPanel;
return new WindowDragHelper(floatingPanelToMove, dragSourceWindow);
}
private sealed class DragVisuals : Control
{
public DragVisuals()
{
AnchorPreset = AnchorPresets.StretchAll;
Offsets = Margin.Zero;
}
public override void Draw()
{
base.Draw();
Render2D.DrawRectangle(new Rectangle(Float2.Zero, Size), Style.Current.SelectionBorder);
}
}
private void AddDockHints()
{
if (_toDock == null)
return;
if (_toDock.RootWindow.Window != _dragSourceWindow)
_toDock.RootWindow.Window.MouseUp += OnMouseUp;
_dockHintDown = AddHintControl(new Float2(0.5f, 1));
_dockHintUp = AddHintControl(new Float2(0.5f, 0));
_dockHintLeft = AddHintControl(new Float2(0, 0.5f));
_dockHintRight = AddHintControl(new Float2(1, 0.5f));
_dockHintCenter = AddHintControl(new Float2(0.5f, 0.5f));
Control AddHintControl(Float2 pivot)
{
DragVisuals hintControl = _toDock.AddChild<DragVisuals>();
hintControl.Size = new Float2(HintControlSize);
hintControl.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
hintControl.Pivot = pivot;
hintControl.PivotRelative = true;
return hintControl;
}
}
private void RemoveDockHints()
{
if (_toDock == null)
return;
if (_toDock.RootWindow.Window != _dragSourceWindow)
_toDock.RootWindow.Window.MouseUp -= OnMouseUp;
_dockHintDown?.Parent.RemoveChild(_dockHintDown);
_dockHintUp?.Parent.RemoveChild(_dockHintUp);
_dockHintLeft?.Parent.RemoveChild(_dockHintLeft);
_dockHintRight?.Parent.RemoveChild(_dockHintRight);
_dockHintCenter?.Parent.RemoveChild(_dockHintCenter);
_dockHintDown = _dockHintUp = _dockHintLeft = _dockHintRight = _dockHintCenter = null;
}
private void UpdateRects(Float2 mousePos)
{
// Cache mouse position
_mouse = mousePos;
// Check intersection with any dock panel
DockPanel dockPanel = null;
if (_toMove.MasterPanel.HitTest(ref _mouse, _toMove, out var hitResults))
{
dockPanel = hitResults[0];
// Prefer panel which currently has focus
foreach (var hit in hitResults)
{
if (hit.RootWindow.Window.IsFocused)
{
dockPanel = hit;
break;
}
}
// Prefer panel in the same window we hit earlier
if (dockPanel?.RootWindow != _toDock?.RootWindow)
{
foreach (var hit in hitResults)
{
if (hit.RootWindow == _toDock?.RootWindow)
{
dockPanel = _toDock;
break;
}
}
}
}
if (dockPanel != _toDock)
{
RemoveDockHints();
_toDock = dockPanel;
AddDockHints();
// Make sure the all the dock hint areas are not under other windows
_toDock?.RootWindow.Window.BringToFront();
//_toDock?.RootWindow.Window.Focus();
// Make the dragged window transparent when dock hints are visible
_toMove.Window.Window.Opacity = _toDock == null ? 1.0f : DragWindowOpacity;
}
// Check dock state to use
bool showProxyHints = _toDock != null;
bool showBorderHints = showProxyHints;
bool showCenterHint = showProxyHints;
Control hoveredHintControl = null;
Float2 hoveredSizeOverride = Float2.Zero;
if (showProxyHints)
{
// If moved window has not only tabs but also child panels disable docking as tab
if (_toMove.ChildPanelsCount > 0)
showCenterHint = false;
// Disable docking windows with one or more dock panels inside
if (_toMove.ChildPanelsCount > 0)
showBorderHints = false;
// Get dock area
_rectDock = _toDock.DockAreaBounds;
// Cache dock rectangles
var size = _rectDock.Size / Platform.DpiScale;
var offset = _toDock.PointFromScreen(_rectDock.Location);
var borderMargin = 4.0f;
var hintWindowsSize = HintControlSize;
var hintWindowsSize2 = hintWindowsSize * 0.5f;
var hintPreviewSize = new Float2(Math.Max(HintControlSize * 2, size.X * 0.5f), Math.Max(HintControlSize * 2, size.Y * 0.5f));
var centerX = size.X * 0.5f;
var centerY = size.Y * 0.5f;
_rUpper = new Rectangle(centerX - hintWindowsSize2, borderMargin, hintWindowsSize, hintWindowsSize) + offset;
_rBottom = new Rectangle(centerX - hintWindowsSize2, size.Y - hintWindowsSize - borderMargin, hintWindowsSize, hintWindowsSize) + offset;
_rLeft = new Rectangle(borderMargin, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
_rRight = new Rectangle(size.X - hintWindowsSize - borderMargin, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
_rCenter = new Rectangle(centerX - hintWindowsSize2, centerY - hintWindowsSize2, hintWindowsSize, hintWindowsSize) + offset;
// Hit test, and calculate the approximation for filled area when hovered over the hint
DockState toSet = DockState.Float;
if (showBorderHints)
{
if (_rUpper.Contains(_toDock.PointFromScreen(_mouse)))
{
toSet = DockState.DockTop;
hoveredHintControl = _dockHintUp;
hoveredSizeOverride = new Float2(size.X, hintPreviewSize.Y);
}
else if (_rBottom.Contains(_toDock.PointFromScreen(_mouse)))
{
toSet = DockState.DockBottom;
hoveredHintControl = _dockHintDown;
hoveredSizeOverride = new Float2(size.X, hintPreviewSize.Y);
}
else if (_rLeft.Contains(_toDock.PointFromScreen(_mouse)))
{
toSet = DockState.DockLeft;
hoveredHintControl = _dockHintLeft;
hoveredSizeOverride = new Float2(hintPreviewSize.X, size.Y);
}
else if (_rRight.Contains(_toDock.PointFromScreen(_mouse)))
{
toSet = DockState.DockRight;
hoveredHintControl = _dockHintRight;
hoveredSizeOverride = new Float2(hintPreviewSize.X, size.Y);
}
}
if (showCenterHint && _rCenter.Contains(_toDock.PointFromScreen(_mouse)))
{
toSet = DockState.DockFill;
hoveredHintControl = _dockHintCenter;
hoveredSizeOverride = new Float2(size.X, size.Y);
}
_toSet = toSet;
}
else
{
_toSet = DockState.Float;
}
// Update sizes and opacity of hint controls
if (_toDock != null)
{
if (hoveredHintControl != _dockHintDown)
{
_dockHintDown.Size = new Float2(HintControlSize);
_dockHintDown.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
}
if (hoveredHintControl != _dockHintLeft)
{
_dockHintLeft.Size = new Float2(HintControlSize);
_dockHintLeft.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
}
if (hoveredHintControl != _dockHintRight)
{
_dockHintRight.Size = new Float2(HintControlSize);
_dockHintRight.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
}
if (hoveredHintControl != _dockHintUp)
{
_dockHintUp.Size = new Float2(HintControlSize);
_dockHintUp.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
}
if (hoveredHintControl != _dockHintCenter)
{
_dockHintCenter.Size = new Float2(HintControlSize);
_dockHintCenter.BackgroundColor = Style.Current.Selection.AlphaMultiplied(0.6f);
}
if (_toSet != DockState.Float)
{
if (hoveredHintControl != null)
{
hoveredHintControl.BackgroundColor = Style.Current.Selection.AlphaMultiplied(1.0f);
hoveredHintControl.Size = hoveredSizeOverride;
}
}
}
// Update hint controls visibility and location
if (showProxyHints)
{
if (hoveredHintControl != _dockHintDown)
_dockHintDown.Location = _rBottom.Location;
if (hoveredHintControl != _dockHintLeft)
_dockHintLeft.Location = _rLeft.Location;
if (hoveredHintControl != _dockHintRight)
_dockHintRight.Location = _rRight.Location;
if (hoveredHintControl != _dockHintUp)
_dockHintUp.Location = _rUpper.Location;
if (hoveredHintControl != _dockHintCenter)
_dockHintCenter.Location = _rCenter.Location;
_dockHintDown.Visible = showProxyHints & showBorderHints;
_dockHintLeft.Visible = showProxyHints & showBorderHints;
_dockHintRight.Visible = showProxyHints & showBorderHints;
_dockHintUp.Visible = showProxyHints & showBorderHints;
_dockHintCenter.Visible = showProxyHints & showCenterHint;
}
}
private void OnMouseUp(ref Float2 location, MouseButton button, ref bool handled)
{
if (button == MouseButton.Left)
Dispose();
}
private void OnUpdate()
{
var mousePos = Platform.MousePosition;
if (_mouse != mousePos)
OnMouseMove(mousePos);
}
private void OnMouseMove(Float2 mousePos)
{
if (_dragSourceWindow != null)
_toMove.Window.Window.Position = mousePos - _dragOffset;
UpdateRects(mousePos);
}
}
}

View File

@@ -180,7 +180,7 @@ namespace FlaxEditor.GUI.Input
Focus(); Focus();
float mousePosition = location.X; float mousePosition = location.X;
if (_thumbRect.Contains(location)) if (_thumbRect.Contains(ref location))
{ {
// Start sliding // Start sliding
_isSliding = true; _isSliding = true;

View File

@@ -266,7 +266,6 @@ namespace FlaxEditor.GUI.Input
return base.OnMouseDown(location, button); return base.OnMouseDown(location, button);
} }
#if !PLATFORM_SDL
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
@@ -293,45 +292,13 @@ namespace FlaxEditor.GUI.Input
base.OnMouseMove(location); base.OnMouseMove(location);
} }
#else
/// <inheritdoc />
public override void OnMouseMoveRelative(Float2 mouseMotion)
{
var location = Root.TrackingMouseOffset;
if (_isSliding)
{
// Update sliding
ApplySliding(Root.TrackingMouseOffset.X * _slideSpeed);
return;
}
// Update cursor type so user knows they can slide value
if (CanUseSliding && SlideRect.Contains(location) && !_isSliding)
{
Cursor = CursorType.SizeWE;
_cursorChanged = true;
}
else if (_cursorChanged && !_isSliding)
{
Cursor = CursorType.Default;
_cursorChanged = false;
}
base.OnMouseMoveRelative(mouseMotion);
}
#endif
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseUp(Float2 location, MouseButton button) public override bool OnMouseUp(Float2 location, MouseButton button)
{ {
if (button == MouseButton.Left && _isSliding) if (button == MouseButton.Left && _isSliding)
{ {
#if !PLATFORM_SDL
// End sliding and return mouse to original location // End sliding and return mouse to original location
RootWindow.MousePosition = _mouseClickedPosition; RootWindow.MousePosition = _mouseClickedPosition;
#endif
EndSliding(); EndSliding();
return true; return true;
} }

View File

@@ -12,6 +12,16 @@ namespace FlaxEditor.GUI
/// <seealso cref="FlaxEngine.GUI.ContainerControl" /> /// <seealso cref="FlaxEngine.GUI.ContainerControl" />
public sealed class MainMenu : ContainerControl public sealed class MainMenu : ContainerControl
{ {
#if PLATFORM_WINDOWS
private bool _useCustomWindowSystem;
private Image _icon;
private Label _title;
private Button _closeButton;
private Button _minimizeButton;
private Button _maximizeButton;
private LocalizedString _charChromeRestore, _charChromeMaximize;
private Window _window;
#endif
private MainMenuButton _selected; private MainMenuButton _selected;
/// <summary> /// <summary>
@@ -50,12 +60,200 @@ namespace FlaxEditor.GUI
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="MainMenu"/> class. /// Initializes a new instance of the <see cref="MainMenu"/> class.
/// </summary> /// </summary>
public MainMenu() /// <param name="mainWindow">The main window.</param>
public MainMenu(RootControl mainWindow)
: base(0, 0, 0, 20) : base(0, 0, 0, 20)
{ {
AutoFocus = false; AutoFocus = false;
AnchorPreset = AnchorPresets.HorizontalStretchTop; AnchorPreset = AnchorPresets.HorizontalStretchTop;
BackgroundColor = Style.Current.LightBackground;
#if PLATFORM_WINDOWS
_useCustomWindowSystem = !Editor.Instance.Options.Options.Interface.UseNativeWindowSystem;
if (_useCustomWindowSystem)
{
BackgroundColor = Style.Current.LightBackground;
Height = 28;
var windowIcon = FlaxEngine.Content.LoadAsyncInternal<Texture>(EditorAssets.WindowIcon);
FontAsset windowIconsFont = FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.WindowIconsFont);
Font iconFont = windowIconsFont?.CreateFont(9);
_window = mainWindow.RootWindow.Window;
_window.HitTest += OnHitTest;
_window.Closed += OnWindowClosed;
ScriptsBuilder.GetBinariesConfiguration(out _, out _, out _, out var configuration);
_icon = new Image
{
Margin = new Margin(6, 6, 6, 6),
Brush = new TextureBrush(windowIcon),
Color = Style.Current.Foreground,
KeepAspectRatio = false,
TooltipText = string.Format("{0}\nVersion {1}\nConfiguration {3}\nGraphics {2}", _window.Title, Globals.EngineVersion, GPUDevice.Instance.RendererType, configuration),
Parent = this,
};
_title = new Label(0, 0, Width, Height)
{
Text = _window.Title,
HorizontalAlignment = TextAlignment.Center,
VerticalAlignment = TextAlignment.Center,
ClipText = true,
TextColor = Style.Current.ForegroundGrey,
TextColorHighlighted = Style.Current.ForegroundGrey,
Parent = this,
};
_closeButton = new Button
{
Text = ((char)EditorAssets.SegMDL2Icons.ChromeClose).ToString(),
Font = new FontReference(iconFont),
BackgroundColor = Color.Transparent,
BorderColor = Color.Transparent,
BorderColorHighlighted = Color.Transparent,
BorderColorSelected = Color.Transparent,
TextColor = Style.Current.Foreground,
Width = 46,
BackgroundColorHighlighted = Color.Red,
BackgroundColorSelected = Color.Red.RGBMultiplied(1.3f),
Parent = this,
};
_closeButton.Clicked += () => _window.Close(ClosingReason.User);
_minimizeButton = new Button
{
Text = ((char)EditorAssets.SegMDL2Icons.ChromeMinimize).ToString(),
Font = new FontReference(iconFont),
BackgroundColor = Color.Transparent,
BorderColor = Color.Transparent,
BorderColorHighlighted = Color.Transparent,
BorderColorSelected = Color.Transparent,
TextColor = Style.Current.Foreground,
Width = 46,
BackgroundColorHighlighted = Style.Current.LightBackground.RGBMultiplied(1.3f),
Parent = this,
};
_minimizeButton.Clicked += () => _window.Minimize();
_maximizeButton = new Button
{
Text = ((char)(_window.IsMaximized ? EditorAssets.SegMDL2Icons.ChromeRestore : EditorAssets.SegMDL2Icons.ChromeMaximize)).ToString(),
Font = new FontReference(iconFont),
BackgroundColor = Color.Transparent,
BorderColor = Color.Transparent,
BorderColorHighlighted = Color.Transparent,
BorderColorSelected = Color.Transparent,
TextColor = Style.Current.Foreground,
Width = 46,
BackgroundColorHighlighted = Style.Current.LightBackground.RGBMultiplied(1.3f),
Parent = this,
};
_maximizeButton.Clicked += () =>
{
if (_window.IsMaximized)
_window.Restore();
else
_window.Maximize();
};
_charChromeRestore = ((char)EditorAssets.SegMDL2Icons.ChromeRestore).ToString();
_charChromeMaximize = ((char)EditorAssets.SegMDL2Icons.ChromeMaximize).ToString();
}
else
#endif
{
BackgroundColor = Style.Current.LightBackground;
}
}
#if PLATFORM_WINDOWS
/// <inheritdoc />
public override void Update(float deltaTime)
{
base.Update(deltaTime);
if (_maximizeButton != null)
{
_maximizeButton.Text = _window.IsMaximized ? _charChromeRestore : _charChromeMaximize;
}
}
private void OnWindowClosed()
{
if (_window != null)
{
_window.HitTest = null;
_window = null;
}
}
private WindowHitCodes OnHitTest(ref Float2 mouse)
{
var dpiScale = _window.DpiScale;
if (_window.IsMinimized)
return WindowHitCodes.NoWhere;
if (!_window.IsMaximized)
{
var pos = _window.ScreenToClient(mouse * dpiScale); // pos is not DPI adjusted
var winSize = _window.Size;
// Distance from which the mouse is considered to be on the border/corner
float distance = 5.0f * dpiScale;
if (pos.Y > winSize.Y - distance && pos.X < distance)
return WindowHitCodes.BottomLeft;
if (pos.X > winSize.X - distance && pos.Y > winSize.Y - distance)
return WindowHitCodes.BottomRight;
if (pos.Y < distance && pos.X < distance)
return WindowHitCodes.TopLeft;
if (pos.Y < distance && pos.X > winSize.X - distance)
return WindowHitCodes.TopRight;
if (pos.X > winSize.X - distance)
return WindowHitCodes.Right;
if (pos.X < distance)
return WindowHitCodes.Left;
if (pos.Y < distance)
return WindowHitCodes.Top;
if (pos.Y > winSize.Y - distance)
return WindowHitCodes.Bottom;
}
var mousePos = PointFromScreen(mouse * dpiScale);
var controlUnderMouse = GetChildAt(mousePos);
var isMouseOverSth = controlUnderMouse != null && controlUnderMouse != _title;
var rb = GetRightButton();
if (rb != null && _minimizeButton != null && new Rectangle(rb.UpperRight, _minimizeButton.BottomLeft - rb.UpperRight).Contains(ref mousePos) && !isMouseOverSth)
return WindowHitCodes.Caption;
return WindowHitCodes.Client;
}
#endif
/// <summary>
/// Return the rightmost button.
/// </summary>
/// <returns>Rightmost button, null if there is no <see cref="MainMenuButton"/></returns>
private MainMenuButton GetRightButton()
{
MainMenuButton b = null;
foreach (var control in Children)
{
if (b == null && control is MainMenuButton)
b = (MainMenuButton)control;
if (control is MainMenuButton && control.Right > b.Right)
b = (MainMenuButton)control;
}
return b;
} }
/// <summary> /// <summary>
@@ -100,6 +298,26 @@ namespace FlaxEditor.GUI
return result; return result;
} }
/// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{
if (base.OnMouseDoubleClick(location, button))
return true;
#if PLATFORM_WINDOWS
var child = GetChildAtRecursive(location);
if (_useCustomWindowSystem && child is not Button && child is not MainMenuButton)
{
if (_window.IsMaximized)
_window.Restore();
else
_window.Maximize();
}
#endif
return true;
}
/// <inheritdoc /> /// <inheritdoc />
public override bool OnKeyDown(KeyboardKeys key) public override bool OnKeyDown(KeyboardKeys key)
{ {
@@ -115,8 +333,16 @@ namespace FlaxEditor.GUI
protected override void PerformLayoutAfterChildren() protected override void PerformLayoutAfterChildren()
{ {
float x = 0; float x = 0;
WindowDecorations decorations = Parent.GetChild<WindowDecorations>();
x += decorations?.Icon?.Width ?? 0; #if PLATFORM_WINDOWS
if (_useCustomWindowSystem)
{
// Icon
_icon.X = x;
_icon.Size = new Float2(Height);
x += _icon.Width;
}
#endif
// Arrange controls // Arrange controls
MainMenuButton rightMostButton = null; MainMenuButton rightMostButton = null;
@@ -135,21 +361,37 @@ namespace FlaxEditor.GUI
x += b.Width; x += b.Width;
} }
} }
// Fill the right side if title and buttons are not present #if PLATFORM_WINDOWS
if (decorations?.Title == null) if (_useCustomWindowSystem)
Width = Parent.Width; {
else // Buttons
Width = x; _closeButton.Height = Height;
_closeButton.X = Width - _closeButton.Width;
_maximizeButton.Height = Height;
_maximizeButton.X = _closeButton.X - _maximizeButton.Width;
_minimizeButton.Height = Height;
_minimizeButton.X = _maximizeButton.X - _minimizeButton.Width;
// Title
_title.Bounds = new Rectangle(x + 2, 0, _minimizeButton.Left - x - 4, Height);
//_title.Text = _title.Width < 300.0f ? Editor.Instance.ProjectInfo.Name : _window.Title;
}
#endif
} }
#if PLATFORM_WINDOWS
/// <inheritdoc /> /// <inheritdoc />
public override void OnDestroy() public override void OnDestroy()
{ {
base.OnDestroy(); base.OnDestroy();
if (_selected != null) if (_window != null)
Selected = null; {
_window.Closed -= OnWindowClosed;
OnWindowClosed();
}
} }
#endif
} }
} }

View File

@@ -42,12 +42,14 @@ namespace FlaxEditor.GUI
Text = text; Text = text;
var style = Style.Current; var style = Style.Current;
if (!Utilities.Utils.UseCustomWindowDecorations()) #if PLATFORM_WINDOWS
if (Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
{ {
BackgroundColorMouseOver = style.BackgroundHighlighted; BackgroundColorMouseOver = style.BackgroundHighlighted;
BackgroundColorMouseOverOpened = style.Background; BackgroundColorMouseOverOpened = style.Background;
} }
else else
#endif
{ {
BackgroundColorMouseOver = BackgroundColorMouseOverOpened = style.LightBackground * 1.3f; BackgroundColorMouseOver = BackgroundColorMouseOverOpened = style.LightBackground * 1.3f;
} }

View File

@@ -144,7 +144,7 @@ namespace FlaxEditor.GUI.Timeline
var k = keyframes[i]; var k = keyframes[i];
var sphere = new BoundingSphere(k.Value, KeyframeSize); var sphere = new BoundingSphere(k.Value, KeyframeSize);
if (sphere.Intersects(selectRay)) if (sphere.Intersects(ref selectRay))
{ {
SelectKeyframe(_track, i, 0); SelectKeyframe(_track, i, 0);
return; return;
@@ -154,7 +154,7 @@ namespace FlaxEditor.GUI.Timeline
{ {
var t = k.Value + k.TangentIn; var t = k.Value + k.TangentIn;
var box = BoundingBox.FromSphere(new BoundingSphere(t, TangentSize)); var box = BoundingBox.FromSphere(new BoundingSphere(t, TangentSize));
if (box.Intersects(selectRay)) if (box.Intersects(ref selectRay))
{ {
SelectKeyframe(_track, i, 1); SelectKeyframe(_track, i, 1);
return; return;
@@ -165,7 +165,7 @@ namespace FlaxEditor.GUI.Timeline
{ {
var t = k.Value + k.TangentOut; var t = k.Value + k.TangentOut;
var box = BoundingBox.FromSphere(new BoundingSphere(t, TangentSize)); var box = BoundingBox.FromSphere(new BoundingSphere(t, TangentSize));
if (box.Intersects(selectRay)) if (box.Intersects(ref selectRay))
{ {
SelectKeyframe(_track, i, 2); SelectKeyframe(_track, i, 2);
return; return;

View File

@@ -115,7 +115,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
if (_isMoving && Float2.DistanceSquared(location, _startMovePos) > 25.0f) if (_isMoving && Float2.DistanceSquared(ref location, ref _startMovePos) > 25.0f)
{ {
_startMovePos = Float2.Minimum; _startMovePos = Float2.Minimum;
var x = PointToParent(location).X; var x = PointToParent(location).X;
@@ -387,7 +387,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
{ {
// Push clipping mask // Push clipping mask
GetDesireClientArea(out var clientArea); GetDesireClientArea(out var clientArea);
Render2D.PushClip(clientArea); Render2D.PushClip(ref clientArea);
var style = Style.Current; var style = Style.Current;
var bounds = new Rectangle(Float2.Zero, Size); var bounds = new Rectangle(Float2.Zero, Size);

View File

@@ -115,7 +115,7 @@ namespace FlaxEditor.GUI
{ {
if (Children[i] is KeyframePoint p) if (Children[i] is KeyframePoint p)
{ {
p.IsSelected = p.Bounds.Intersects(selectionRect); p.IsSelected = p.Bounds.Intersects(ref selectionRect);
} }
} }
} }
@@ -401,7 +401,7 @@ namespace FlaxEditor.GUI
Cursor = CursorType.Default; Cursor = CursorType.Default;
// Check if no move has been made at all // Check if no move has been made at all
if (Float2.Distance(location, _rightMouseDownPos) < 2.0f) if (Float2.Distance(ref location, ref _rightMouseDownPos) < 2.0f)
{ {
var selectionCount = _editor.SelectionCount; var selectionCount = _editor.SelectionCount;
var point = GetChildAt(location) as KeyframePoint; var point = GetChildAt(location) as KeyframePoint;

View File

@@ -50,14 +50,14 @@ namespace FlaxEditor.GUI.Timeline.GUI
var color = (_timeline.IsMovingPositionHandle ? style.SelectionBorder : style.Foreground).AlphaMultiplied(0.6f); var color = (_timeline.IsMovingPositionHandle ? style.SelectionBorder : style.Foreground).AlphaMultiplied(0.6f);
Matrix3x3.RotationZ(Mathf.PiOverTwo, out var m1); Matrix3x3.RotationZ(Mathf.PiOverTwo, out var m1);
var m2 = Matrix3x3.Translation2D(0, timeAxisHeaderOffset); var m2 = Matrix3x3.Translation2D(0, timeAxisHeaderOffset);
Matrix3x3.Multiply(m1, m2, out var m3); Matrix3x3.Multiply(ref m1, ref m2, out var m3);
Render2D.PushTransform(m3); Render2D.PushTransform(ref m3);
// TODO: Convert to its own sprite or 9 slice // TODO: Convert to its own sprite or 9 slice
Render2D.DrawSprite(icon, new Rectangle(new Float2(10, -icon.Size.X * 0.5f - 1), Size + new Float2(0, 1)), color); Render2D.DrawSprite(icon, new Rectangle(new Float2(10, -icon.Size.X * 0.5f - 1), Size + new Float2(0, 1)), color);
Render2D.FillRectangle(new Rectangle(new Float2(-6, -icon.Size.Y * 0.5f + 7), new Float2(timeAxisOverlap, 5)), color); Render2D.FillRectangle(new Rectangle(new Float2(-6, -icon.Size.Y * 0.5f + 7), new Float2(timeAxisOverlap, 5)), color);
Render2D.PopTransform(); Render2D.PopTransform();
var textMatrix = Matrix3x3.Translation2D(12, timeAxisHeaderOffset); var textMatrix = Matrix3x3.Translation2D(12, timeAxisHeaderOffset);
Render2D.PushTransform(textMatrix); Render2D.PushTransform(ref textMatrix);
Render2D.DrawText(style.FontSmall, labelText, style.Foreground, new Float2(2, -6)); Render2D.DrawText(style.FontSmall, labelText, style.Foreground, new Float2(2, -6));
Render2D.PopTransform(); Render2D.PopTransform();

View File

@@ -356,7 +356,7 @@ namespace FlaxEditor.GUI.Timeline
{ {
Render2D.DrawLine(bounds.UpperLeft, bounds.BottomLeft, moveColor, moveThickness); Render2D.DrawLine(bounds.UpperLeft, bounds.BottomLeft, moveColor, moveThickness);
} }
else if (IsMouseOver && CanResize && MoveLeftEdgeRect.Contains(_mouseLocation)) else if (IsMouseOver && CanResize && MoveLeftEdgeRect.Contains(ref _mouseLocation))
{ {
Render2D.DrawLine(bounds.UpperLeft, bounds.BottomLeft, Color.Yellow); Render2D.DrawLine(bounds.UpperLeft, bounds.BottomLeft, Color.Yellow);
} }
@@ -364,7 +364,7 @@ namespace FlaxEditor.GUI.Timeline
{ {
Render2D.DrawLine(bounds.UpperRight, bounds.BottomRight, moveColor, moveThickness); Render2D.DrawLine(bounds.UpperRight, bounds.BottomRight, moveColor, moveThickness);
} }
else if (IsMouseOver && CanResize && MoveRightEdgeRect.Contains(_mouseLocation)) else if (IsMouseOver && CanResize && MoveRightEdgeRect.Contains(ref _mouseLocation))
{ {
Render2D.DrawLine(bounds.UpperRight, bounds.BottomRight, Color.Yellow); Render2D.DrawLine(bounds.UpperRight, bounds.BottomRight, Color.Yellow);
} }
@@ -384,8 +384,8 @@ namespace FlaxEditor.GUI.Timeline
_startMoveLocation = Root.MousePosition; _startMoveLocation = Root.MousePosition;
_startMoveStartFrame = StartFrame; _startMoveStartFrame = StartFrame;
_startMoveDuration = DurationFrames; _startMoveDuration = DurationFrames;
_startMoveLeftEdge = MoveLeftEdgeRect.Contains(location) && CanResize; _startMoveLeftEdge = MoveLeftEdgeRect.Contains(ref location) && CanResize;
_startMoveRightEdge = MoveRightEdgeRect.Contains(location) && CanResize; _startMoveRightEdge = MoveRightEdgeRect.Contains(ref location) && CanResize;
StartMouseCapture(true); StartMouseCapture(true);
if (_startMoveLeftEdge || _startMoveRightEdge) if (_startMoveLeftEdge || _startMoveRightEdge)
return true; return true;

View File

@@ -337,7 +337,7 @@ namespace FlaxEditor.GUI.Timeline
DebugDraw.DrawSphere(sphere, selected ? Color.Yellow : Color.Red); DebugDraw.DrawSphere(sphere, selected ? Color.Yellow : Color.Red);
sphere.Radius *= 0.95f; sphere.Radius *= 0.95f;
DebugDraw.DrawSphere(sphere, new Color(1, 0, 0, coveredAlpha), 0, false); DebugDraw.DrawSphere(sphere, new Color(1, 0, 0, coveredAlpha), 0, false);
if (select && sphere.Intersects(selectRay)) if (select && sphere.Intersects(ref selectRay))
SelectKeyframeGizmo(curveTrack, i, 0); SelectKeyframeGizmo(curveTrack, i, 0);
if (!k.TangentIn.IsZero) if (!k.TangentIn.IsZero)
@@ -349,7 +349,7 @@ namespace FlaxEditor.GUI.Timeline
var box = BoundingBox.FromSphere(new BoundingSphere(t, EditCurveTrackGizmo.TangentSize)); var box = BoundingBox.FromSphere(new BoundingSphere(t, EditCurveTrackGizmo.TangentSize));
DebugDraw.DrawBox(box, selected ? Color.Yellow : Color.AliceBlue); DebugDraw.DrawBox(box, selected ? Color.Yellow : Color.AliceBlue);
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(coveredAlpha), 0, false); DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(coveredAlpha), 0, false);
if (select && box.Intersects(selectRay)) if (select && box.Intersects(ref selectRay))
SelectKeyframeGizmo(curveTrack, i, 2); SelectKeyframeGizmo(curveTrack, i, 2);
} }
@@ -362,7 +362,7 @@ namespace FlaxEditor.GUI.Timeline
var box = BoundingBox.FromSphere(new BoundingSphere(t, EditCurveTrackGizmo.TangentSize)); var box = BoundingBox.FromSphere(new BoundingSphere(t, EditCurveTrackGizmo.TangentSize));
DebugDraw.DrawBox(box, selected ? Color.Yellow : Color.AliceBlue); DebugDraw.DrawBox(box, selected ? Color.Yellow : Color.AliceBlue);
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(coveredAlpha), 0, false); DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(coveredAlpha), 0, false);
if (select && box.Intersects(selectRay)) if (select && box.Intersects(ref selectRay))
SelectKeyframeGizmo(curveTrack, i, 2); SelectKeyframeGizmo(curveTrack, i, 2);
} }

View File

@@ -2078,7 +2078,7 @@ namespace FlaxEditor.GUI.Timeline
if (button == MouseButton.Right && _isRightMouseButtonDown) if (button == MouseButton.Right && _isRightMouseButtonDown)
{ {
_isRightMouseButtonDown = false; _isRightMouseButtonDown = false;
if (Float2.Distance(location, _rightMouseButtonDownPos) < 4.0f) if (Float2.Distance(ref location, ref _rightMouseButtonDownPos) < 4.0f)
ShowContextMenu(location); ShowContextMenu(location);
} }
@@ -2243,7 +2243,7 @@ namespace FlaxEditor.GUI.Timeline
foreach (var media in _tracks[i].Media) foreach (var media in _tracks[i].Media)
{ {
if (media.Bounds.Intersects(mediaRect)) if (media.Bounds.Intersects(ref mediaRect))
{ {
SelectedMedia.Add(media); SelectedMedia.Add(media);
selectionChanged = true; selectionChanged = true;

View File

@@ -810,7 +810,7 @@ namespace FlaxEditor.GUI.Timeline
/// <returns>True if hits it.</returns> /// <returns>True if hits it.</returns>
protected virtual bool TestHeaderHit(ref Float2 location) protected virtual bool TestHeaderHit(ref Float2 location)
{ {
return new Rectangle(0, 0, Width, HeaderHeight).Contains(location); return new Rectangle(0, 0, Width, HeaderHeight).Contains(ref location);
} }
/// <summary> /// <summary>

View File

@@ -208,7 +208,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
// Hit-test dot // Hit-test dot
var size = Height - 2.0f; var size = Height - 2.0f;
var rect = new Rectangle(new Float2(size * -0.5f) + Size * 0.5f, new Float2(size)); var rect = new Rectangle(new Float2(size * -0.5f) + Size * 0.5f, new Float2(size));
return rect.Contains(location); return rect.Contains(ref location);
} }
return base.ContainsPoint(ref location, precise); return base.ContainsPoint(ref location, precise);

View File

@@ -527,7 +527,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
{ {
_output = GPUDevice.Instance.CreateTexture("CameraCutMedia.Output"); _output = GPUDevice.Instance.CreateTexture("CameraCutMedia.Output");
var desc = GPUTextureDescription.New2D(Width, Height, PixelFormat.R8G8B8A8_UNorm); var desc = GPUTextureDescription.New2D(Width, Height, PixelFormat.R8G8B8A8_UNorm);
_output.Init(desc); _output.Init(ref desc);
} }
if (_task == null) if (_task == null)
{ {

View File

@@ -258,7 +258,7 @@ namespace FlaxEditor.GUI.Tree
} }
var nodeArea = new Rectangle(pos, child.Size); var nodeArea = new Rectangle(pos, child.Size);
if (child.IsExpanded && range.Intersects(nodeArea)) if (child.IsExpanded && range.Intersects(ref nodeArea))
WalkSelectRangeExpandedTree(selection, child, ref range); WalkSelectRangeExpandedTree(selection, child, ref range);
} }
} }

View File

@@ -555,7 +555,7 @@ namespace FlaxEditor.GUI.Tree
/// <returns>True if hits it.</returns> /// <returns>True if hits it.</returns>
protected virtual bool TestHeaderHit(ref Float2 location) protected virtual bool TestHeaderHit(ref Float2 location)
{ {
return _headerRect.Contains(location); return _headerRect.Contains(ref location);
} }
/// <summary> /// <summary>
@@ -864,14 +864,14 @@ namespace FlaxEditor.GUI.Tree
var child = children[i]; var child = children[i];
if (!child.Visible) if (!child.Visible)
continue; continue;
Render2D.PushTransform(child._cachedTransform); Render2D.PushTransform(ref child._cachedTransform);
child.Draw(); child.Draw();
Render2D.PopTransform(); Render2D.PopTransform();
} }
static Rectangle GetChildGlobalRectangle(Control control, ref Matrix3x3 globalTransform) static Rectangle GetChildGlobalRectangle(Control control, ref Matrix3x3 globalTransform)
{ {
Matrix3x3.Multiply(control._cachedTransform, globalTransform, out var globalChildTransform); Matrix3x3.Multiply(ref control._cachedTransform, ref globalTransform, out var globalChildTransform);
return new Rectangle(globalChildTransform.M31, globalChildTransform.M32, control.Width * globalChildTransform.M11, control.Height * globalChildTransform.M22); return new Rectangle(globalChildTransform.M31, globalChildTransform.M32, control.Width * globalChildTransform.M11, control.Height * globalChildTransform.M22);
} }
} }
@@ -882,7 +882,7 @@ namespace FlaxEditor.GUI.Tree
var child = children[i]; var child = children[i];
if (child.Visible) if (child.Visible)
{ {
Render2D.PushTransform(child._cachedTransform); Render2D.PushTransform(ref child._cachedTransform);
child.Draw(); child.Draw();
Render2D.PopTransform(); Render2D.PopTransform();
} }

View File

@@ -24,7 +24,7 @@ namespace FlaxEditor.GUI.Tree
foreach (var child in Addons) foreach (var child in Addons)
{ {
Render2D.PushTransform(child._cachedTransform); Render2D.PushTransform(ref child._cachedTransform);
child.Draw(); child.Draw();
Render2D.PopTransform(); Render2D.PopTransform();
} }

View File

@@ -1,342 +0,0 @@
// Copyright (c) Wojciech Figat. All rights reserved.
using System;
using FlaxEditor.GUI.Docking;
using FlaxEditor.Options;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.GUI;
/// <summary>
/// Represents the title bar of the window with buttons.
/// </summary>
/// <seealso cref="FlaxEngine.GUI.ContainerControl" />
public class WindowDecorations : ContainerControl
{
private Image _icon;
private Label _title;
private Button _closeButton;
private Button _minimizeButton;
private Button _maximizeButton;
private LocalizedString _charChromeRestore, _charChromeMaximize;
private Window _window;
/// <summary>
/// The title label in the title bar.
/// </summary>
public Label Title => _title;
/// <summary>
/// The icon used in the title bar.
/// </summary>
public Image Icon => _icon;
/// <summary>
/// The tooltip shown when hovering over the icon.
/// </summary>
public string IconTooltipText
{
get => _icon?.TooltipText ?? null;
set
{
if (_icon != null)
_icon.TooltipText = value;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="WindowDecorations"/> class.
/// </summary>
/// <param name="window">The window.</param>
/// <param name="iconOnly">When set, omit drawing title and buttons.</param>
public WindowDecorations(RootControl window, bool iconOnly = false)
: base(0, 0, 0, 20)
{
_window = window.RootWindow.Window;
AutoFocus = false;
AnchorPreset = AnchorPresets.HorizontalStretchTop;
BackgroundColor = Color.Transparent;
var windowIcon = FlaxEngine.Content.LoadAsyncInternal<Texture>(EditorAssets.WindowIcon);
_icon = new Image
{
Margin = new Margin(4, 4, 4, 4),
Brush = new TextureBrush(windowIcon),
Color = Style.Current.Foreground,
BackgroundColor = Style.Current.LightBackground,
KeepAspectRatio = false,
Parent = this,
};
if (!iconOnly)
{
_icon.Margin = new Margin(6, 6, 6, 6);
Height = 28;
_window.HitTest += OnHitTest;
_window.Closed += OnWindowClosed;
FontAsset windowIconsFont = FlaxEngine.Content.LoadAsyncInternal<FontAsset>(EditorAssets.WindowIconsFont);
Font iconFont = windowIconsFont?.CreateFont(9);
_title = new Label(0, 0, Width, Height)
{
Text = _window.Title,
HorizontalAlignment = TextAlignment.Center,
VerticalAlignment = TextAlignment.Center,
ClipText = true,
TextColor = Style.Current.ForegroundGrey,
TextColorHighlighted = Style.Current.ForegroundGrey,
BackgroundColor = Style.Current.LightBackground,
Parent = this,
};
_closeButton = new Button
{
Text = ((char)EditorAssets.SegMDL2Icons.ChromeClose).ToString(),
Font = new FontReference(iconFont),
BackgroundColor = Style.Current.LightBackground,
BorderColor = Color.Transparent,
BorderColorHighlighted = Color.Transparent,
BorderColorSelected = Color.Transparent,
TextColor = Style.Current.Foreground,
Width = 46,
BackgroundColorHighlighted = Color.Red,
BackgroundColorSelected = Color.Red.RGBMultiplied(1.3f),
Parent = this,
};
_closeButton.Clicked += () => _window.Close(ClosingReason.User);
_minimizeButton = new Button
{
Text = ((char)EditorAssets.SegMDL2Icons.ChromeMinimize).ToString(),
Font = new FontReference(iconFont),
BackgroundColor = Style.Current.LightBackground,
BorderColor = Color.Transparent,
BorderColorHighlighted = Color.Transparent,
BorderColorSelected = Color.Transparent,
TextColor = Style.Current.Foreground,
Width = 46,
BackgroundColorHighlighted = Style.Current.LightBackground.RGBMultiplied(1.3f),
Parent = this,
};
_minimizeButton.Clicked += () => _window.Minimize();
_maximizeButton = new Button
{
Text = ((char)(_window.IsMaximized ? EditorAssets.SegMDL2Icons.ChromeRestore : EditorAssets.SegMDL2Icons.ChromeMaximize)).ToString(),
Font = new FontReference(iconFont),
BackgroundColor = Style.Current.LightBackground,
BorderColor = Color.Transparent,
BorderColorHighlighted = Color.Transparent,
BorderColorSelected = Color.Transparent,
TextColor = Style.Current.Foreground,
Width = 46,
BackgroundColorHighlighted = Style.Current.LightBackground.RGBMultiplied(1.3f),
Parent = this,
};
_maximizeButton.Clicked += () =>
{
if (_window.IsMaximized)
_window.Restore();
else
_window.Maximize();
};
_charChromeRestore = ((char)EditorAssets.SegMDL2Icons.ChromeRestore).ToString();
_charChromeMaximize = ((char)EditorAssets.SegMDL2Icons.ChromeMaximize).ToString();
}
}
/// <inheritdoc />
public override void Update(float deltaTime)
{
base.Update(deltaTime);
if (_maximizeButton != null)
{
var maximizeText = _window.IsMaximized ? _charChromeRestore : _charChromeMaximize;
if (_maximizeButton.Text != maximizeText)
_maximizeButton.Text = maximizeText;
}
}
private void OnWindowClosed()
{
if (_window != null)
{
_window.HitTest -= OnHitTest;
_window = null;
}
}
/// <summary>
/// Perform hit test on the window.
/// </summary>
/// <param name="mouse">The mouse position</param>
/// <returns>The hit code for given position.</returns>
protected virtual WindowHitCodes OnHitTest(ref Float2 mouse)
{
if (_window.IsMinimized)
return WindowHitCodes.NoWhere;
var dpiScale = _window.DpiScale;
var pos = _window.ScreenToClient(mouse * dpiScale); // pos is not DPI adjusted
if (!_window.IsMaximized)
{
var winSize = _window.Size;
// Distance from which the mouse is considered to be on the border/corner
float distance = 5.0f * dpiScale;
if (pos.Y > winSize.Y - distance && pos.X < distance)
return WindowHitCodes.BottomLeft;
if (pos.X > winSize.X - distance && pos.Y > winSize.Y - distance)
return WindowHitCodes.BottomRight;
if (pos.Y < distance && pos.X < distance)
return WindowHitCodes.TopLeft;
if (pos.Y < distance && pos.X > winSize.X - distance)
return WindowHitCodes.TopRight;
if (pos.X > winSize.X - distance)
return WindowHitCodes.Right;
if (pos.X < distance)
return WindowHitCodes.Left;
if (pos.Y < distance)
return WindowHitCodes.Top;
if (pos.Y > winSize.Y - distance)
return WindowHitCodes.Bottom;
}
var controlUnderMouse = GetChildAt(pos, control => control != _title);
if (_title.Bounds.Contains(pos) && controlUnderMouse == null)
return WindowHitCodes.Caption;
return WindowHitCodes.Client;
}
/// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{
// These may not work with main window due to SDL not passing mouse events
// when interacting with hit tests on caption area...
if (Title.Bounds.Contains(location) && button == MouseButton.Left)
{
if (_window.IsMaximized)
_window.Restore();
else
_window.Maximize();
return true;
}
else if (Icon.Bounds.Contains(location) && button == MouseButton.Left)
{
_window.Close(ClosingReason.User);
return true;
}
return base.OnMouseDoubleClick(location, button);
}
/// <inheritdoc />
protected override void PerformLayoutAfterChildren()
{
// Calculate extents for title bounds area excluding the icon and main menu area
float x = 0;
// Icon
if (_icon != null)
{
_icon.X = x;
_icon.Size = new Float2(Height);
x += _icon.Width;
}
// Main menu if present
if (Parent.GetChild<MainMenu>() is MainMenu mainMenu)
{
for (int i = 0; i < mainMenu.Children.Count; i++)
{
var c = mainMenu.Children[i];
if (c is MainMenuButton b && c.Visible)
{
b.Bounds = new Rectangle(x, 0, b.Width, Height);
x += b.Width;
}
}
}
// Buttons
float rightMostButtonX = Width;
if (_closeButton != null)
{
_closeButton.Height = Height;
_closeButton.X = rightMostButtonX - _closeButton.Width;
rightMostButtonX = _closeButton.X;
}
if (_maximizeButton != null)
{
_maximizeButton.Height = Height;
_maximizeButton.X = rightMostButtonX - _maximizeButton.Width;
rightMostButtonX = _maximizeButton.X;
}
if (_minimizeButton != null)
{
_minimizeButton.Height = Height;
_minimizeButton.X = rightMostButtonX - _minimizeButton.Width;
rightMostButtonX = _minimizeButton.X;
}
// Title
if (_title != null)
{
_title.Text = _window.Title;
_title.Bounds = new Rectangle(x, 0, rightMostButtonX - x, Height);
}
}
/// <inheritdoc />
public override void Draw()
{
base.Draw();
DrawBorders();
}
/// <summary>
/// Draw borders around the window.
/// </summary>
public virtual void DrawBorders()
{
var win = RootWindow.Window;
if (win.IsMaximized)
return;
if (Editor.Instance.UI.StatusBar == null)
return;
const float thickness = 1.0f;
Color color = Editor.Instance.UI.StatusBar.StatusColor;
Rectangle rect = new Rectangle(thickness * 0.5f, thickness * 0.5f, Parent.Width - thickness, Parent.Height - thickness);
Render2D.DrawRectangle(rect, color);
}
/// <inheritdoc />
public override void OnDestroy()
{
base.OnDestroy();
if (_window != null)
{
_window.Closed -= OnWindowClosed;
OnWindowClosed();
}
}
}

View File

@@ -56,9 +56,9 @@ namespace FlaxEditor.Gizmo
var width = output.Width; var width = output.Width;
var height = output.Height; var height = output.Height;
var desc = GPUTextureDescription.New2D(width, height, format, GPUTextureFlags.RenderTarget | GPUTextureFlags.ShaderResource, 1, 1, msaaLevel); var desc = GPUTextureDescription.New2D(width, height, format, GPUTextureFlags.RenderTarget | GPUTextureFlags.ShaderResource, 1, 1, msaaLevel);
var target = RenderTargetPool.Get(desc); var target = RenderTargetPool.Get(ref desc);
desc = GPUTextureDescription.New2D(width, height, PixelFormat.D24_UNorm_S8_UInt, GPUTextureFlags.DepthStencil, 1, 1, msaaLevel); desc = GPUTextureDescription.New2D(width, height, PixelFormat.D24_UNorm_S8_UInt, GPUTextureFlags.DepthStencil, 1, 1, msaaLevel);
var targetDepth = RenderTargetPool.Get(desc); var targetDepth = RenderTargetPool.Get(ref desc);
// Copy frame and clear depth // Copy frame and clear depth
context.Draw(target, input); context.Draw(target, input);
@@ -81,16 +81,16 @@ namespace FlaxEditor.Gizmo
} }
// Sort draw calls // Sort draw calls
renderList.SortDrawCalls(renderContext, false, DrawCallsListType.GBuffer); renderList.SortDrawCalls(ref renderContext, false, DrawCallsListType.GBuffer);
renderList.SortDrawCalls(renderContext, false, DrawCallsListType.GBufferNoDecals); renderList.SortDrawCalls(ref renderContext, false, DrawCallsListType.GBufferNoDecals);
renderList.SortDrawCalls(renderContext, true, DrawCallsListType.Forward); renderList.SortDrawCalls(ref renderContext, true, DrawCallsListType.Forward);
// Perform the rendering // Perform the rendering
renderContext.View.Pass = DrawPass.GBuffer; renderContext.View.Pass = DrawPass.GBuffer;
renderList.ExecuteDrawCalls(renderContext, DrawCallsListType.GBuffer); renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.GBuffer);
renderList.ExecuteDrawCalls(renderContext, DrawCallsListType.GBufferNoDecals); renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.GBufferNoDecals);
renderContext.View.Pass = DrawPass.Forward; renderContext.View.Pass = DrawPass.Forward;
renderList.ExecuteDrawCalls(renderContext, DrawCallsListType.Forward); renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.Forward);
// Resolve MSAA texture // Resolve MSAA texture
if (enableMsaa) if (enableMsaa)

View File

@@ -70,7 +70,7 @@ namespace FlaxEditor.Gizmo
_vertexBuffer = new GPUBuffer(); _vertexBuffer = new GPUBuffer();
var layout = GPUVertexLayout.Get([new VertexElement(VertexElement.Types.Position, 0, 0, false, PixelFormat.R32G32B32_Float)]); var layout = GPUVertexLayout.Get([new VertexElement(VertexElement.Types.Position, 0, 0, false, PixelFormat.R32G32B32_Float)]);
var desc = GPUBufferDescription.Vertex(layout, sizeof(Float3), 4); var desc = GPUBufferDescription.Vertex(layout, sizeof(Float3), 4);
_vertexBuffer.Init(desc); _vertexBuffer.Init(ref desc);
} }
if (_indexBuffer == null) if (_indexBuffer == null)
{ {
@@ -78,7 +78,7 @@ namespace FlaxEditor.Gizmo
fixed (uint* ptr = _triangles) fixed (uint* ptr = _triangles)
{ {
var desc = GPUBufferDescription.Index(sizeof(uint), _triangles.Length, new IntPtr(ptr)); var desc = GPUBufferDescription.Index(sizeof(uint), _triangles.Length, new IntPtr(ptr));
_indexBuffer.Init(desc); _indexBuffer.Init(ref desc);
} }
} }
if (_psGrid == null) if (_psGrid == null)
@@ -90,7 +90,7 @@ namespace FlaxEditor.Gizmo
desc.VS = _shader.GPU.GetVS("VS_Grid"); desc.VS = _shader.GPU.GetVS("VS_Grid");
desc.PS = _shader.GPU.GetPS("PS_Grid"); desc.PS = _shader.GPU.GetPS("PS_Grid");
desc.DepthWriteEnable = false; desc.DepthWriteEnable = false;
_psGrid.Init(desc); _psGrid.Init(ref desc);
} }
// Update vertices of the plane // Update vertices of the plane
@@ -113,8 +113,8 @@ namespace FlaxEditor.Gizmo
if (cb != IntPtr.Zero) if (cb != IntPtr.Zero)
{ {
var data = new Data(); var data = new Data();
Matrix.Multiply(renderContext.View.View, renderContext.View.Projection, out var viewProjection); Matrix.Multiply(ref renderContext.View.View, ref renderContext.View.Projection, out var viewProjection);
Matrix.Transpose(viewProjection, out data.ViewProjectionMatrix); Matrix.Transpose(ref viewProjection, out data.ViewProjectionMatrix);
data.ViewPos = renderContext.View.WorldPosition; data.ViewPos = renderContext.View.WorldPosition;
data.GridColor = options.Viewport.ViewportGridColor; data.GridColor = options.Viewport.ViewportGridColor;
data.Far = renderContext.View.Far; data.Far = renderContext.View.Far;

View File

@@ -128,7 +128,7 @@ namespace FlaxEditor.Gizmo
// Pick a temporary depth buffer // Pick a temporary depth buffer
var desc = GPUTextureDescription.New2D(input.Width, input.Height, PixelFormat.D32_Float, GPUTextureFlags.DepthStencil | GPUTextureFlags.ShaderResource); var desc = GPUTextureDescription.New2D(input.Width, input.Height, PixelFormat.D32_Float, GPUTextureFlags.DepthStencil | GPUTextureFlags.ShaderResource);
var customDepth = RenderTargetPool.Get(desc); var customDepth = RenderTargetPool.Get(ref desc);
context.ClearDepth(customDepth.View()); context.ClearDepth(customDepth.View());
// Draw objects to depth buffer // Draw objects to depth buffer
@@ -148,7 +148,7 @@ namespace FlaxEditor.Gizmo
_material.SetParameterValue("OutlineColor1", _color1); _material.SetParameterValue("OutlineColor1", _color1);
_material.SetParameterValue("CustomDepth", customDepth); _material.SetParameterValue("CustomDepth", customDepth);
_material.SetParameterValue("ViewInfo", new Float4(1.0f / projection.M11, 1.0f / projection.M22, far / (far - near), (-far * near) / (far - near) / far)); _material.SetParameterValue("ViewInfo", new Float4(1.0f / projection.M11, 1.0f / projection.M22, far / (far - near), (-far * near) / (far - near) / far));
Renderer.DrawPostFxMaterial(context, renderContext, _material, output, input.View()); Renderer.DrawPostFxMaterial(context, ref renderContext, _material, output, input.View());
// Cleanup // Cleanup
RenderTargetPool.Release(customDepth); RenderTargetPool.Release(customDepth);

View File

@@ -129,7 +129,7 @@ namespace FlaxEditor.Gizmo
if (_selectionParents[i] is ActorNode actorNode) if (_selectionParents[i] is ActorNode actorNode)
{ {
var b = actorNode.Actor.EditorBoxChildren; var b = actorNode.Actor.EditorBoxChildren;
BoundingBox.Merge(editorBounds, b, out editorBounds); BoundingBox.Merge(ref editorBounds, ref b, out editorBounds);
bottomToCenter = Mathf.Min(bottomToCenter, actorNode.Actor.Position.Y - editorBounds.Minimum.Y); bottomToCenter = Mathf.Min(bottomToCenter, actorNode.Actor.Position.Y - editorBounds.Minimum.Y);
} }
} }

View File

@@ -135,7 +135,7 @@ namespace FlaxEditor.Gizmo
Mesh sphereMesh = _modelSphere.LODs[0].Meshes[0]; Mesh sphereMesh = _modelSphere.LODs[0].Meshes[0];
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
Matrix.Multiply(m3, world, out m1); Matrix.Multiply(ref m3, ref world, out m1);
mx1 = m1; mx1 = m1;
mx1.M41 += 0.05f; mx1.M41 += 0.05f;
@@ -149,44 +149,44 @@ namespace FlaxEditor.Gizmo
// X axis // X axis
Matrix.RotationY(-Mathf.PiOverTwo, out m2); Matrix.RotationY(-Mathf.PiOverTwo, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance xAxisMaterialTransform = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX; MaterialInstance xAxisMaterialTransform = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
transAxisMesh.Draw(renderContext, xAxisMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Y axis // Y axis
Matrix.RotationX(Mathf.PiOverTwo, out m2); Matrix.RotationX(Mathf.PiOverTwo, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance yAxisMaterialTransform = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY; MaterialInstance yAxisMaterialTransform = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
transAxisMesh.Draw(renderContext, yAxisMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Z axis // Z axis
Matrix.RotationX(Mathf.Pi, out m2); Matrix.RotationX(Mathf.Pi, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance zAxisMaterialTransform = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ; MaterialInstance zAxisMaterialTransform = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
transAxisMesh.Draw(renderContext, zAxisMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// XY plane // XY plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f)); m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance xyPlaneMaterialTransform = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX; MaterialInstance xyPlaneMaterialTransform = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
cubeMesh.Draw(renderContext, xyPlaneMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// ZX plane // ZX plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale)); m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance zxPlaneMaterialTransform = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisY; MaterialInstance zxPlaneMaterialTransform = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
cubeMesh.Draw(renderContext, zxPlaneMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// YZ plane // YZ plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale)); m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance yzPlaneMaterialTransform = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisZ; MaterialInstance yzPlaneMaterialTransform = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
cubeMesh.Draw(renderContext, yzPlaneMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Center sphere // Center sphere
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
sphereMesh.Draw(renderContext, isCenter ? _materialAxisFocus : _materialSphere, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
break; break;
} }
@@ -199,24 +199,24 @@ namespace FlaxEditor.Gizmo
// X axis // X axis
Matrix.RotationZ(Mathf.PiOverTwo, out m2); Matrix.RotationZ(Mathf.PiOverTwo, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX; MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
rotationAxisMesh.Draw(renderContext, xAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Y axis // Y axis
MaterialInstance yAxisMaterialRotate = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY; MaterialInstance yAxisMaterialRotate = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
rotationAxisMesh.Draw(renderContext, yAxisMaterialRotate, m1, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); rotationAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m1, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Z axis // Z axis
Matrix.RotationX(-Mathf.PiOverTwo, out m2); Matrix.RotationX(-Mathf.PiOverTwo, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ; MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
rotationAxisMesh.Draw(renderContext, zAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Center box // Center box
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
sphereMesh.Draw(renderContext, isCenter ? _materialAxisFocus : _materialSphere, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
break; break;
} }
@@ -229,44 +229,44 @@ namespace FlaxEditor.Gizmo
// X axis // X axis
Matrix.RotationY(-Mathf.PiOverTwo, out m2); Matrix.RotationY(-Mathf.PiOverTwo, out m2);
Matrix.Multiply(m2, mx1, out m3); Matrix.Multiply(ref m2, ref mx1, out m3);
MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX; MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
scaleAxisMesh.Draw(renderContext, xAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Y axis // Y axis
Matrix.RotationX(Mathf.PiOverTwo, out m2); Matrix.RotationX(Mathf.PiOverTwo, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance yAxisMaterialRotate = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY; MaterialInstance yAxisMaterialRotate = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
scaleAxisMesh.Draw(renderContext, yAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Z axis // Z axis
Matrix.RotationX(Mathf.Pi, out m2); Matrix.RotationX(Mathf.Pi, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ; MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
scaleAxisMesh.Draw(renderContext, zAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// XY plane // XY plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f)); m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance xyPlaneMaterialScale = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX; MaterialInstance xyPlaneMaterialScale = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
cubeMesh.Draw(renderContext, xyPlaneMaterialScale, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// ZX plane // ZX plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale)); m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance zxPlaneMaterialScale = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisZ; MaterialInstance zxPlaneMaterialScale = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
cubeMesh.Draw(renderContext, zxPlaneMaterialScale, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// YZ plane // YZ plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale)); m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
MaterialInstance yzPlaneMaterialScale = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisY; MaterialInstance yzPlaneMaterialScale = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
cubeMesh.Draw(renderContext, yzPlaneMaterialScale, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
// Center box // Center box
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
Matrix.Multiply(m2, m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
sphereMesh.Draw(renderContext, isCenter ? _materialAxisFocus : _materialSphere, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
break; break;
} }
@@ -278,7 +278,7 @@ namespace FlaxEditor.Gizmo
Transform t = _vertexSnapObject?.Transform ?? _vertexSnapObjectTo.Transform; Transform t = _vertexSnapObject?.Transform ?? _vertexSnapObjectTo.Transform;
Vector3 p = t.LocalToWorld(_vertexSnapObject != null ? _vertexSnapPoint : _vertexSnapPointTo); Vector3 p = t.LocalToWorld(_vertexSnapObject != null ? _vertexSnapPoint : _vertexSnapPointTo);
Matrix matrix = new Transform(p, t.Orientation, new Float3(gizmoModelsScale2RealGizmoSize)).GetWorld(); Matrix matrix = new Transform(p, t.Orientation, new Float3(gizmoModelsScale2RealGizmoSize)).GetWorld();
cubeMesh.Draw(renderContext, _materialSphere, matrix, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder); cubeMesh.Draw(ref renderContext, _materialSphere, ref matrix, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
} }
} }
} }

View File

@@ -36,7 +36,7 @@ namespace FlaxEditor.Gizmo
private bool IntersectsRotateCircle(Vector3 normal, ref Ray ray, out Real distance) private bool IntersectsRotateCircle(Vector3 normal, ref Ray ray, out Real distance)
{ {
var plane = new Plane(Vector3.Zero, normal); var plane = new Plane(Vector3.Zero, normal);
if (!plane.Intersects(ray, out distance)) if (!plane.Intersects(ref ray, out distance))
return false; return false;
Vector3 hitPoint = ray.Position + ray.Direction * distance; Vector3 hitPoint = ray.Position + ray.Direction * distance;
Real distanceNormalized = hitPoint.Length / RotateRadiusRaw; Real distanceNormalized = hitPoint.Length / RotateRadiusRaw;
@@ -50,8 +50,8 @@ namespace FlaxEditor.Gizmo
// Transform ray into local space of the gizmo // Transform ray into local space of the gizmo
Ray localRay; Ray localRay;
_gizmoWorld.WorldToLocalVector(ray.Direction, out localRay.Direction); _gizmoWorld.WorldToLocalVector(ref ray.Direction, out localRay.Direction);
_gizmoWorld.WorldToLocal(ray.Position, out localRay.Position); _gizmoWorld.WorldToLocal(ref ray.Position, out localRay.Position);
// Find gizmo collisions with mouse // Find gizmo collisions with mouse
Real closestIntersection = Real.MaxValue; Real closestIntersection = Real.MaxValue;
@@ -62,19 +62,19 @@ namespace FlaxEditor.Gizmo
case Mode.Translate: case Mode.Translate:
{ {
// Axis boxes collision // Axis boxes collision
if (XAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection) if (XAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.X; _activeAxis = Axis.X;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (YAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection) if (YAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.Y; _activeAxis = Axis.Y;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (ZAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection) if (ZAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.Z; _activeAxis = Axis.Z;
closestIntersection = intersection; closestIntersection = intersection;
@@ -83,25 +83,25 @@ namespace FlaxEditor.Gizmo
// Quad planes collision // Quad planes collision
if (closestIntersection >= float.MaxValue) if (closestIntersection >= float.MaxValue)
closestIntersection = float.MinValue; closestIntersection = float.MinValue;
if (XYBox.Intersects(localRay, out intersection) && intersection > closestIntersection) if (XYBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{ {
_activeAxis = Axis.XY; _activeAxis = Axis.XY;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (XZBox.Intersects(localRay, out intersection) && intersection > closestIntersection) if (XZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{ {
_activeAxis = Axis.ZX; _activeAxis = Axis.ZX;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (YZBox.Intersects(localRay, out intersection) && intersection > closestIntersection) if (YZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{ {
_activeAxis = Axis.YZ; _activeAxis = Axis.YZ;
closestIntersection = intersection; closestIntersection = intersection;
} }
/*// Center /*// Center
if (CenterBoxRaw.Intersects(localRay, out intersection) && intersection > closestIntersection) if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{ {
_activeAxis = Axis.Center; _activeAxis = Axis.Center;
closestIntersection = intersection; closestIntersection = intersection;
@@ -133,17 +133,17 @@ namespace FlaxEditor.Gizmo
case Mode.Scale: case Mode.Scale:
{ {
// Boxes collision // Boxes collision
if (XAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection) if (XAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.X; _activeAxis = Axis.X;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (YAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection) if (YAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.Y; _activeAxis = Axis.Y;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (ZAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection) if (ZAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.Z; _activeAxis = Axis.Z;
closestIntersection = intersection; closestIntersection = intersection;
@@ -153,24 +153,24 @@ namespace FlaxEditor.Gizmo
if (closestIntersection >= float.MaxValue) if (closestIntersection >= float.MaxValue)
closestIntersection = float.MinValue; closestIntersection = float.MinValue;
if (XYBox.Intersects(localRay, out intersection) && intersection > closestIntersection) if (XYBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{ {
_activeAxis = Axis.XY; _activeAxis = Axis.XY;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (XZBox.Intersects(localRay, out intersection) && intersection > closestIntersection) if (XZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{ {
_activeAxis = Axis.ZX; _activeAxis = Axis.ZX;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (YZBox.Intersects(localRay, out intersection) && intersection > closestIntersection) if (YZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{ {
_activeAxis = Axis.YZ; _activeAxis = Axis.YZ;
closestIntersection = intersection; closestIntersection = intersection;
} }
// Center // Center
if (CenterBoxRaw.Intersects(localRay, out intersection) && intersection > closestIntersection) if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{ {
_activeAxis = Axis.Center; _activeAxis = Axis.Center;
closestIntersection = intersection; closestIntersection = intersection;

View File

@@ -212,10 +212,10 @@ namespace FlaxEditor.Gizmo
Vector3 delta = Vector3.Zero; Vector3 delta = Vector3.Zero;
Ray ray = Owner.MouseRay; Ray ray = Owner.MouseRay;
Matrix.RotationQuaternion(_gizmoWorld.Orientation, out var rotationMatrix); Matrix.RotationQuaternion(ref _gizmoWorld.Orientation, out var rotationMatrix);
Matrix.Invert(rotationMatrix, out var invRotationMatrix); Matrix.Invert(ref rotationMatrix, out var invRotationMatrix);
ray.Position = Vector3.Transform(ray.Position, invRotationMatrix); ray.Position = Vector3.Transform(ray.Position, invRotationMatrix);
Vector3.TransformNormal(ray.Direction, invRotationMatrix, out ray.Direction); Vector3.TransformNormal(ref ray.Direction, ref invRotationMatrix, out ray.Direction);
var position = Position; var position = Position;
var planeXY = new Plane(Vector3.Backward, Vector3.Transform(position, invRotationMatrix).Z); var planeXY = new Plane(Vector3.Backward, Vector3.Transform(position, invRotationMatrix).Z);
@@ -232,7 +232,7 @@ namespace FlaxEditor.Gizmo
case Axis.X: case Axis.X:
{ {
var plane = planeDotXY > planeDotZX ? planeXY : planeZX; var plane = planeDotXY > planeDotZX ? planeXY : planeZX;
if (ray.Intersects(plane, out intersection)) if (ray.Intersects(ref plane, out intersection))
{ {
_intersectPosition = ray.GetPoint(intersection); _intersectPosition = ray.GetPoint(intersection);
if (!_lastIntersectionPosition.IsZero) if (!_lastIntersectionPosition.IsZero)
@@ -244,7 +244,7 @@ namespace FlaxEditor.Gizmo
case Axis.Y: case Axis.Y:
{ {
var plane = planeDotXY > planeDotYZ ? planeXY : planeYZ; var plane = planeDotXY > planeDotYZ ? planeXY : planeYZ;
if (ray.Intersects(plane, out intersection)) if (ray.Intersects(ref plane, out intersection))
{ {
_intersectPosition = ray.GetPoint(intersection); _intersectPosition = ray.GetPoint(intersection);
if (!_lastIntersectionPosition.IsZero) if (!_lastIntersectionPosition.IsZero)
@@ -256,7 +256,7 @@ namespace FlaxEditor.Gizmo
case Axis.Z: case Axis.Z:
{ {
var plane = planeDotZX > planeDotYZ ? planeZX : planeYZ; var plane = planeDotZX > planeDotYZ ? planeZX : planeYZ;
if (ray.Intersects(plane, out intersection)) if (ray.Intersects(ref plane, out intersection))
{ {
_intersectPosition = ray.GetPoint(intersection); _intersectPosition = ray.GetPoint(intersection);
if (!_lastIntersectionPosition.IsZero) if (!_lastIntersectionPosition.IsZero)
@@ -267,7 +267,7 @@ namespace FlaxEditor.Gizmo
} }
case Axis.YZ: case Axis.YZ:
{ {
if (ray.Intersects(planeYZ, out intersection)) if (ray.Intersects(ref planeYZ, out intersection))
{ {
_intersectPosition = ray.GetPoint(intersection); _intersectPosition = ray.GetPoint(intersection);
if (!_lastIntersectionPosition.IsZero) if (!_lastIntersectionPosition.IsZero)
@@ -288,7 +288,7 @@ namespace FlaxEditor.Gizmo
} }
case Axis.XY: case Axis.XY:
{ {
if (ray.Intersects(planeXY, out intersection)) if (ray.Intersects(ref planeXY, out intersection))
{ {
_intersectPosition = ray.GetPoint(intersection); _intersectPosition = ray.GetPoint(intersection);
if (!_lastIntersectionPosition.IsZero) if (!_lastIntersectionPosition.IsZero)
@@ -309,7 +309,7 @@ namespace FlaxEditor.Gizmo
} }
case Axis.ZX: case Axis.ZX:
{ {
if (ray.Intersects(planeZX, out intersection)) if (ray.Intersects(ref planeZX, out intersection))
{ {
_intersectPosition = ray.GetPoint(intersection); _intersectPosition = ray.GetPoint(intersection);
if (!_lastIntersectionPosition.IsZero) if (!_lastIntersectionPosition.IsZero)
@@ -332,7 +332,7 @@ namespace FlaxEditor.Gizmo
{ {
var gizmoToView = Position - Owner.ViewPosition; var gizmoToView = Position - Owner.ViewPosition;
var plane = new Plane(-Vector3.Normalize(gizmoToView), gizmoToView.Length); var plane = new Plane(-Vector3.Normalize(gizmoToView), gizmoToView.Length);
if (ray.Intersects(plane, out intersection)) if (ray.Intersects(ref plane, out intersection))
{ {
_intersectPosition = ray.GetPoint(intersection); _intersectPosition = ray.GetPoint(intersection);
if (!_lastIntersectionPosition.IsZero) if (!_lastIntersectionPosition.IsZero)
@@ -473,11 +473,11 @@ namespace FlaxEditor.Gizmo
dir = Float3.Forward * _gizmoWorld.Orientation; dir = Float3.Forward * _gizmoWorld.Orientation;
Float3 viewDir = Owner.ViewPosition - Position; Float3 viewDir = Owner.ViewPosition - Position;
Float3.Dot(viewDir, dir, out float dot); Float3.Dot(ref viewDir, ref dir, out float dot);
if (dot < 0.0f) if (dot < 0.0f)
delta *= -1; delta *= -1;
Quaternion.RotationAxis(dir, delta, out _rotationDelta); Quaternion.RotationAxis(ref dir, delta, out _rotationDelta);
break; break;
} }

View File

@@ -240,7 +240,7 @@ namespace FlaxEditor
{ {
foreach (var widget in _widgets) foreach (var widget in _widgets)
{ {
if (widget.Bounds.Contains(location)) if (widget.Bounds.Contains(ref location))
{ {
// Initialize widget movement // Initialize widget movement
_activeWidget = widget; _activeWidget = widget;
@@ -326,7 +326,7 @@ namespace FlaxEditor
{ {
foreach (var widget in _widgets) foreach (var widget in _widgets)
{ {
if (widget.Bounds.Contains(location)) if (widget.Bounds.Contains(ref location))
{ {
Cursor = widget.Cursor; Cursor = widget.Cursor;
cursorChanged = true; cursorChanged = true;
@@ -499,7 +499,7 @@ namespace FlaxEditor
var min = Float2.Min(upperLeft, bottomRight); var min = Float2.Min(upperLeft, bottomRight);
var max = Float2.Max(upperLeft, bottomRight); var max = Float2.Max(upperLeft, bottomRight);
var pixelRange = (max - min) * ViewScale; var pixelRange = (max - min) * ViewScale;
Render2D.PushClip(viewRect); Render2D.PushClip(ref viewRect);
DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X); DrawAxis(Float2.UnitX, viewRect, min.X, max.X, pixelRange.X);
DrawAxis(Float2.UnitY, viewRect, min.Y, max.Y, pixelRange.Y); DrawAxis(Float2.UnitY, viewRect, min.Y, max.Y, pixelRange.Y);
Render2D.PopClip(); Render2D.PopClip();
@@ -605,7 +605,7 @@ namespace FlaxEditor
if (!drawAnySelectedControl) if (!drawAnySelectedControl)
{ {
drawAnySelectedControl = true; drawAnySelectedControl = true;
Render2D.PushTransform(_cachedTransform); Render2D.PushTransform(ref _cachedTransform);
} }
var options = Editor.Instance.Options.Options.Visual; var options = Editor.Instance.Options.Options.Visual;
@@ -643,10 +643,10 @@ namespace FlaxEditor
DrawControlWidget(uiControl, ref ur, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, -1), CursorType.SizeNESW); DrawControlWidget(uiControl, ref ur, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, -1), CursorType.SizeNESW);
DrawControlWidget(uiControl, ref bl, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, 1), CursorType.SizeNESW); DrawControlWidget(uiControl, ref bl, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, 1), CursorType.SizeNESW);
DrawControlWidget(uiControl, ref br, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, 1), CursorType.SizeNWSE); DrawControlWidget(uiControl, ref br, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, 1), CursorType.SizeNWSE);
Float2.Lerp(ul, bl, 0.5f, out var el); Float2.Lerp(ref ul, ref bl, 0.5f, out var el);
Float2.Lerp(ur, br, 0.5f, out var er); Float2.Lerp(ref ur, ref br, 0.5f, out var er);
Float2.Lerp(ul, ur, 0.5f, out var eu); Float2.Lerp(ref ul, ref ur, 0.5f, out var eu);
Float2.Lerp(bl, br, 0.5f, out var eb); Float2.Lerp(ref bl, ref br, 0.5f, out var eb);
DrawControlWidget(uiControl, ref el, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, 0), CursorType.SizeWE); DrawControlWidget(uiControl, ref el, ref mousePos, ref widgetHandleSize, viewScale, new Float2(-1, 0), CursorType.SizeWE);
DrawControlWidget(uiControl, ref er, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, 0), CursorType.SizeWE); DrawControlWidget(uiControl, ref er, ref mousePos, ref widgetHandleSize, viewScale, new Float2(1, 0), CursorType.SizeWE);
DrawControlWidget(uiControl, ref eu, ref mousePos, ref widgetHandleSize, viewScale, new Float2(0, -1), CursorType.SizeNS); DrawControlWidget(uiControl, ref eu, ref mousePos, ref widgetHandleSize, viewScale, new Float2(0, -1), CursorType.SizeNS);
@@ -749,7 +749,7 @@ namespace FlaxEditor
default: break; default: break;
} }
} }
if (rect.Contains(mousePos)) if (rect.Contains(ref mousePos))
{ {
Render2D.FillRectangle(rect, style.Foreground); Render2D.FillRectangle(rect, style.Foreground);
Render2D.DrawRectangle(rect, style.SelectionBorder); Render2D.DrawRectangle(rect, style.SelectionBorder);

View File

@@ -124,7 +124,7 @@ public sealed class ViewportRubberBandSelector
public void ProjectPoint(Vector3 worldSpaceLocation, out Float2 viewportSpaceLocation) public void ProjectPoint(Vector3 worldSpaceLocation, out Float2 viewportSpaceLocation)
{ {
worldSpaceLocation -= _origin; worldSpaceLocation -= _origin;
_viewport.Project(worldSpaceLocation, _viewProjection, out var projected); _viewport.Project(ref worldSpaceLocation, ref _viewProjection, out var projected);
viewportSpaceLocation = new Float2((float)projected.X, (float)projected.Y); viewportSpaceLocation = new Float2((float)projected.X, (float)projected.Y);
} }
@@ -132,7 +132,7 @@ public sealed class ViewportRubberBandSelector
{ {
bounds.Minimum -= _origin; bounds.Minimum -= _origin;
bounds.Maximum -= _origin; bounds.Maximum -= _origin;
return _frustum.Contains(bounds); return _frustum.Contains(ref bounds);
} }
} }

View File

@@ -402,11 +402,10 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa
break; break;
} }
} }
WindowsManager::WindowsLocker.Unlock();
for (const auto& e : inputEvents) for (const auto& e : inputEvents)
{ {
auto window = e.Target ? e.Target : defaultWindow; auto window = e.Target ? e.Target : defaultWindow;
if (!window || window->IsClosed()) if (!window)
continue; continue;
switch (e.Type) switch (e.Type)
{ {
@@ -436,14 +435,12 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa
case InputDevice::EventType::MouseMove: case InputDevice::EventType::MouseMove:
window->OnMouseMove(window->ScreenToClient(e.MouseData.Position)); window->OnMouseMove(window->ScreenToClient(e.MouseData.Position));
break; break;
case InputDevice::EventType::MouseMoveRelative:
window->OnMouseMoveRelative(e.MouseMovementData.PositionRelative);
break;
case InputDevice::EventType::MouseLeave: case InputDevice::EventType::MouseLeave:
window->OnMouseLeave(); window->OnMouseLeave();
break; break;
} }
} }
WindowsManager::WindowsLocker.Unlock();
} }
WindowsManager::WindowsLocker.Lock(); WindowsManager::WindowsLocker.Lock();
Array<Window*, InlinedAllocation<32>> windows; Array<Window*, InlinedAllocation<32>> windows;

View File

@@ -334,7 +334,7 @@ Window* ManagedEditor::GetMainWindow()
ASSERT(HasManagedInstance()); ASSERT(HasManagedInstance());
const auto method = GetClass()->GetMethod("GetMainWindowPtr"); const auto method = GetClass()->GetMethod("GetMainWindowPtr");
ASSERT(method); ASSERT(method);
return (Window*)MUtils::Unbox<void*>(method->Invoke(GetManagedInstance(), nullptr, nullptr), true); return (Window*)MUtils::Unbox<void*>(method->Invoke(GetManagedInstance(), nullptr, nullptr));
} }
bool ManagedEditor::CanReloadScripts() bool ManagedEditor::CanReloadScripts()
@@ -346,7 +346,7 @@ bool ManagedEditor::CanReloadScripts()
Internal_CanReloadScripts = GetClass()->GetMethod("Internal_CanReloadScripts"); Internal_CanReloadScripts = GetClass()->GetMethod("Internal_CanReloadScripts");
ASSERT(Internal_CanReloadScripts); ASSERT(Internal_CanReloadScripts);
} }
return MUtils::Unbox<bool>(Internal_CanReloadScripts->Invoke(GetManagedInstance(), nullptr, nullptr), true); return MUtils::Unbox<bool>(Internal_CanReloadScripts->Invoke(GetManagedInstance(), nullptr, nullptr));
} }
bool ManagedEditor::CanAutoBuildCSG() bool ManagedEditor::CanAutoBuildCSG()
@@ -365,7 +365,7 @@ bool ManagedEditor::CanAutoBuildCSG()
Internal_CanAutoBuildCSG = GetClass()->GetMethod("Internal_CanAutoBuildCSG"); Internal_CanAutoBuildCSG = GetClass()->GetMethod("Internal_CanAutoBuildCSG");
ASSERT(Internal_CanAutoBuildCSG); ASSERT(Internal_CanAutoBuildCSG);
} }
return MUtils::Unbox<bool>(Internal_CanAutoBuildCSG->Invoke(GetManagedInstance(), nullptr, nullptr), true); return MUtils::Unbox<bool>(Internal_CanAutoBuildCSG->Invoke(GetManagedInstance(), nullptr, nullptr));
} }
bool ManagedEditor::CanAutoBuildNavMesh() bool ManagedEditor::CanAutoBuildNavMesh()
@@ -384,7 +384,7 @@ bool ManagedEditor::CanAutoBuildNavMesh()
Internal_CanAutoBuildNavMesh = GetClass()->GetMethod("Internal_CanAutoBuildNavMesh"); Internal_CanAutoBuildNavMesh = GetClass()->GetMethod("Internal_CanAutoBuildNavMesh");
ASSERT(Internal_CanAutoBuildNavMesh); ASSERT(Internal_CanAutoBuildNavMesh);
} }
return MUtils::Unbox<bool>(Internal_CanAutoBuildNavMesh->Invoke(GetManagedInstance(), nullptr, nullptr), true); return MUtils::Unbox<bool>(Internal_CanAutoBuildNavMesh->Invoke(GetManagedInstance(), nullptr, nullptr));
} }
bool ManagedEditor::HasGameViewportFocus() const bool ManagedEditor::HasGameViewportFocus() const
@@ -397,8 +397,7 @@ bool ManagedEditor::HasGameViewportFocus() const
Internal_HasGameViewportFocus = GetClass()->GetMethod("Internal_HasGameViewportFocus"); Internal_HasGameViewportFocus = GetClass()->GetMethod("Internal_HasGameViewportFocus");
ASSERT(Internal_HasGameViewportFocus); ASSERT(Internal_HasGameViewportFocus);
} }
auto invk = Internal_HasGameViewportFocus->Invoke(GetManagedInstance(), nullptr, nullptr); result = MUtils::Unbox<bool>(Internal_HasGameViewportFocus->Invoke(GetManagedInstance(), nullptr, nullptr));
result = MUtils::Unbox<bool>(invk, true);
} }
return result; return result;
} }
@@ -496,7 +495,7 @@ bool ManagedEditor::OnAppExit()
Internal_OnAppExit = GetClass()->GetMethod("Internal_OnAppExit"); Internal_OnAppExit = GetClass()->GetMethod("Internal_OnAppExit");
ASSERT(Internal_OnAppExit); ASSERT(Internal_OnAppExit);
} }
return MUtils::Unbox<bool>(Internal_OnAppExit->Invoke(GetManagedInstance(), nullptr, nullptr), true); return MUtils::Unbox<bool>(Internal_OnAppExit->Invoke(GetManagedInstance(), nullptr, nullptr));
} }
void ManagedEditor::RequestStartPlayOnEditMode() void ManagedEditor::RequestStartPlayOnEditMode()

View File

@@ -1013,7 +1013,7 @@ namespace FlaxEditor.Modules
ContentItem item; ContentItem item;
if (path.EndsWith(".cs")) if (path.EndsWith(".cs"))
item = new CSharpScriptItem(path); item = new CSharpScriptItem(path);
else if (path.EndsWith(".cpp") || path.EndsWith(".h") || path.EndsWith(".c") || path.EndsWith(".hpp")) else if (path.EndsWith(".cpp") || path.EndsWith(".h"))
item = new CppScriptItem(path); item = new CppScriptItem(path);
else if (path.EndsWith(".shader") || path.EndsWith(".hlsl")) else if (path.EndsWith(".shader") || path.EndsWith(".hlsl"))
item = new ShaderSourceItem(path); item = new ShaderSourceItem(path);

View File

@@ -222,7 +222,7 @@ namespace FlaxEditor.Modules
outputExtension = extension; outputExtension = extension;
// Check if can place source files here // Check if can place source files here
if (!targetLocation.CanHaveScripts && (extension == ".cs" || extension == ".cpp" || extension == ".h" || extension == ".c" || extension == ".hpp")) if (!targetLocation.CanHaveScripts && (extension == ".cs" || extension == ".cpp" || extension == ".h"))
{ {
// Error // Error
Editor.LogWarning(string.Format("Cannot import \'{0}\' to \'{1}\'. The target directory cannot have scripts.", inputPath, targetLocation.Node.Path)); Editor.LogWarning(string.Format("Cannot import \'{0}\' to \'{1}\'. The target directory cannot have scripts.", inputPath, targetLocation.Node.Path));

View File

@@ -267,7 +267,7 @@ namespace FlaxEditor.Modules
} }
/// <inheritdoc /> /// <inheritdoc />
public override void OnPlayBeginning() public override void OnPlayBegin()
{ {
Editor.Windows.FlashMainWindow(); Editor.Windows.FlashMainWindow();

View File

@@ -334,9 +334,6 @@ namespace FlaxEditor.Modules.SourceCodeEditing
} }
} }
} }
if (editor == null)
editor = Editor.Instance.CodeEditing.Editors[0];
Editor.Instance.CodeEditing.SelectedEditor = editor; Editor.Instance.CodeEditing.SelectedEditor = editor;
} }

View File

@@ -40,8 +40,9 @@ namespace FlaxEditor.Modules.SourceCodeEditing
var codeEditing = Editor.Instance.CodeEditing; var codeEditing = Editor.Instance.CodeEditing;
var vsCode = codeEditing.GetInBuildEditor(CodeEditorTypes.VSCode); var vsCode = codeEditing.GetInBuildEditor(CodeEditorTypes.VSCode);
var rider = codeEditing.GetInBuildEditor(CodeEditorTypes.Rider); var rider = codeEditing.GetInBuildEditor(CodeEditorTypes.Rider);
var zed = codeEditing.GetInBuildEditor(CodeEditorTypes.Zed);
#if PLATFORM_WINDOWS #if PLATFORM_WINDOW
// Favor the newest Visual Studio // Favor the newest Visual Studio
for (int i = (int)CodeEditorTypes.VS2026; i >= (int)CodeEditorTypes.VS2008; i--) for (int i = (int)CodeEditorTypes.VS2026; i >= (int)CodeEditorTypes.VS2008; i--)
{ {
@@ -66,6 +67,8 @@ namespace FlaxEditor.Modules.SourceCodeEditing
_currentEditor = vsCode; _currentEditor = vsCode;
else if (rider != null) else if (rider != null)
_currentEditor = rider; _currentEditor = rider;
else if (zed != null)
_currentEditor = zed;
else else
_currentEditor = codeEditing.GetInBuildEditor(CodeEditorTypes.SystemDefault); _currentEditor = codeEditing.GetInBuildEditor(CodeEditorTypes.SystemDefault);
} }
@@ -74,7 +77,7 @@ namespace FlaxEditor.Modules.SourceCodeEditing
public string Name => "Default"; public string Name => "Default";
/// <inheritdoc /> /// <inheritdoc />
public string GenerateProjectCustomArgs => _currentEditor?.GenerateProjectCustomArgs; public string GenerateProjectCustomArgs => null;
/// <inheritdoc /> /// <inheritdoc />
public void OpenSolution() public void OpenSolution()

View File

@@ -22,14 +22,75 @@ namespace FlaxEditor.Modules.SourceCodeEditing
public InBuildSourceCodeEditor(CodeEditorTypes type) public InBuildSourceCodeEditor(CodeEditorTypes type)
{ {
Type = type; Type = type;
Name = CodeEditingManager.GetName(type); switch (type)
{
case CodeEditorTypes.Custom:
Name = "Custom";
break;
case CodeEditorTypes.SystemDefault:
Name = "System Default";
break;
case CodeEditorTypes.VS2008:
Name = "Visual Studio 2008";
break;
case CodeEditorTypes.VS2010:
Name = "Visual Studio 2010";
break;
case CodeEditorTypes.VS2012:
Name = "Visual Studio 2012";
break;
case CodeEditorTypes.VS2013:
Name = "Visual Studio 2013";
break;
case CodeEditorTypes.VS2015:
Name = "Visual Studio 2015";
break;
case CodeEditorTypes.VS2017:
Name = "Visual Studio 2017";
break;
case CodeEditorTypes.VS2019:
Name = "Visual Studio 2019";
break;
case CodeEditorTypes.VS2022:
Name = "Visual Studio 2022";
break;
case CodeEditorTypes.VS2026:
Name = "Visual Studio 2026";
break;
case CodeEditorTypes.VSCode:
Name = "Visual Studio Code";
break;
case CodeEditorTypes.VSCodeInsiders:
Name = "Visual Studio Code - Insiders";
break;
case CodeEditorTypes.Rider:
Name = "Rider";
break;
case CodeEditorTypes.Zed:
Name = "Zed";
break;
default: throw new ArgumentOutOfRangeException(nameof(type), type, null);
}
} }
/// <inheritdoc /> /// <inheritdoc />
public string Name { get; set; } public string Name { get; set; }
/// <inheritdoc /> /// <inheritdoc />
public string GenerateProjectCustomArgs => CodeEditingManager.GetGenerateProjectCustomArgs(Type); public string GenerateProjectCustomArgs
{
get
{
switch (Type)
{
case CodeEditorTypes.VSCodeInsiders:
case CodeEditorTypes.VSCode: return "-vscode -vs2022";
case CodeEditorTypes.Rider: return "-vs2022";
case CodeEditorTypes.Zed: return "-vs2022";
default: return null;
}
}
}
/// <inheritdoc /> /// <inheritdoc />
public void OpenSolution() public void OpenSolution()

View File

@@ -16,6 +16,7 @@ using FlaxEditor.Windows;
using FlaxEngine; using FlaxEngine;
using FlaxEngine.GUI; using FlaxEngine.GUI;
using FlaxEngine.Json; using FlaxEngine.Json;
using DockHintWindow = FlaxEditor.GUI.Docking.DockHintWindow;
using MasterDockPanel = FlaxEditor.GUI.Docking.MasterDockPanel; using MasterDockPanel = FlaxEditor.GUI.Docking.MasterDockPanel;
using FlaxEditor.Content.Settings; using FlaxEditor.Content.Settings;
using FlaxEditor.Options; using FlaxEditor.Options;
@@ -28,40 +29,6 @@ namespace FlaxEditor.Modules
/// <seealso cref="FlaxEditor.Modules.EditorModule" /> /// <seealso cref="FlaxEditor.Modules.EditorModule" />
public sealed class UIModule : EditorModule public sealed class UIModule : EditorModule
{ {
private class MainWindowDecorations : WindowDecorations
{
public MainWindowDecorations(RootControl window, bool iconOnly)
: base(window, iconOnly)
{
}
/// <inheritdoc />
public override bool OnKeyDown(KeyboardKeys key)
{
if (base.OnKeyDown(key))
return true;
// Fallback to the edit window for shortcuts
var editor = Editor.Instance;
return editor.Windows.EditWin.InputActions.Process(editor, this, key);
}
/// <inheritdoc />
public override void DrawBorders()
{
// Draw main window borders if using a custom style
var win = RootWindow.Window;
if (win.IsMaximized)
return;
var color = Editor.Instance.UI.StatusBar.StatusColor;
var rect = new Rectangle(0.5f, 0.5f, Parent.Width - 1.0f, Parent.Height - 1.0f - StatusBar.DefaultHeight);
Render2D.DrawLine(rect.UpperLeft, rect.UpperRight, color);
Render2D.DrawLine(rect.UpperLeft, rect.BottomLeft, color);
Render2D.DrawLine(rect.UpperRight, rect.BottomRight, color);
}
}
private Label _progressLabel; private Label _progressLabel;
private ProgressBar _progressBar; private ProgressBar _progressBar;
private Button _outputLogButton; private Button _outputLogButton;
@@ -177,11 +144,6 @@ namespace FlaxEditor.Modules
/// </summary> /// </summary>
public MainMenu MainMenu; public MainMenu MainMenu;
/// <summary>
/// The window decorations (title bar with buttons)
/// </summary>
public WindowDecorations WindowDecorations;
/// <summary> /// <summary>
/// The tool strip control. /// The tool strip control.
/// </summary> /// </summary>
@@ -464,11 +426,19 @@ namespace FlaxEditor.Modules
InitToolstrip(mainWindow); InitToolstrip(mainWindow);
InitStatusBar(mainWindow); InitStatusBar(mainWindow);
InitDockPanel(mainWindow); InitDockPanel(mainWindow);
InitWindowDecorations(mainWindow);
Editor.Options.OptionsChanged += OnOptionsChanged; Editor.Options.OptionsChanged += OnOptionsChanged;
mainWindow.PerformLayout(true); // Add dummy control for drawing the main window borders if using a custom style
#if PLATFORM_WINDOWS
if (!Editor.Options.Options.Interface.UseNativeWindowSystem)
#endif
{
mainWindow.AddChild(new CustomWindowBorderControl
{
Size = Float2.Zero,
});
}
} }
private void InitViewportScaleOptions() private void InitViewportScaleOptions()
@@ -540,6 +510,23 @@ namespace FlaxEditor.Modules
} }
} }
private class CustomWindowBorderControl : Control
{
/// <inheritdoc />
public override void Draw()
{
var win = RootWindow.Window;
if (win.IsMaximized)
return;
var color = Editor.Instance.UI.StatusBar.StatusColor;
var rect = new Rectangle(0.5f, 0.5f, Parent.Width - 1.0f, Parent.Height - 1.0f - StatusBar.DefaultHeight);
Render2D.DrawLine(rect.UpperLeft, rect.UpperRight, color);
Render2D.DrawLine(rect.UpperLeft, rect.BottomLeft, color);
Render2D.DrawLine(rect.UpperRight, rect.BottomRight, color);
}
}
/// <inheritdoc /> /// <inheritdoc />
public override void OnEndInit() public override void OnEndInit()
{ {
@@ -571,6 +558,13 @@ namespace FlaxEditor.Modules
UpdateToolstrip(); UpdateToolstrip();
} }
/// <inheritdoc />
public override void OnExit()
{
// Cleanup dock panel hint proxy windows (Flax will destroy them by var but it's better to clear them earlier)
DockHintWindow.Proxy.Dispose();
}
private IColorPickerDialog ShowPickColorDialog(Control targetControl, Color initialValue, ColorValueBox.ColorPickerEvent colorChanged, ColorValueBox.ColorPickerClosedEvent pickerClosed, bool useDynamicEditing) private IColorPickerDialog ShowPickColorDialog(Control targetControl, Color initialValue, ColorValueBox.ColorPickerEvent colorChanged, ColorValueBox.ColorPickerClosedEvent pickerClosed, bool useDynamicEditing)
{ {
var dialog = new ColorPickerDialog(initialValue, colorChanged, pickerClosed, useDynamicEditing); var dialog = new ColorPickerDialog(initialValue, colorChanged, pickerClosed, useDynamicEditing);
@@ -624,12 +618,10 @@ namespace FlaxEditor.Modules
private void InitMainMenu(RootControl mainWindow) private void InitMainMenu(RootControl mainWindow)
{ {
MainMenu = new MainMenu() MainMenu = new MainMenu(mainWindow)
{ {
Parent = mainWindow Parent = mainWindow
}; };
if (Utilities.Utils.UseCustomWindowDecorations(isMainWindow: true))
MainMenu.Height = 28;
var inputOptions = Editor.Options.Options.Input; var inputOptions = Editor.Options.Options.Input;
@@ -722,7 +714,6 @@ namespace FlaxEditor.Modules
_menuToolsBuildCSGMesh = cm.AddButton("Build CSG mesh", inputOptions.BuildCSG, Editor.BuildCSG); _menuToolsBuildCSGMesh = cm.AddButton("Build CSG mesh", inputOptions.BuildCSG, Editor.BuildCSG);
_menuToolsBuildNavMesh = cm.AddButton("Build Nav Mesh", inputOptions.BuildNav, Editor.BuildNavMesh); _menuToolsBuildNavMesh = cm.AddButton("Build Nav Mesh", inputOptions.BuildNav, Editor.BuildNavMesh);
_menuToolsBuildAllMeshesSDF = cm.AddButton("Build all meshes SDF", inputOptions.BuildSDF, Editor.BuildAllMeshesSDF); _menuToolsBuildAllMeshesSDF = cm.AddButton("Build all meshes SDF", inputOptions.BuildSDF, Editor.BuildAllMeshesSDF);
_menuToolsBuildAllMeshesSDF.LinkTooltip("Generates Sign Distance Field texture for all meshes used in loaded scenes. Use with 'F' key pressed to force rebuild SDF for meshes with existing one.");
cm.AddSeparator(); cm.AddSeparator();
cm.AddButton("Game Cooker", Editor.Windows.GameCookerWin.FocusOrShow); cm.AddButton("Game Cooker", Editor.Windows.GameCookerWin.FocusOrShow);
_menuToolsCancelBuilding = cm.AddButton("Cancel building game", () => GameCooker.Cancel()); _menuToolsCancelBuilding = cm.AddButton("Cancel building game", () => GameCooker.Cancel());
@@ -771,20 +762,6 @@ namespace FlaxEditor.Modules
cm.AddButton("Information about Flax", () => new AboutDialog().Show()); cm.AddButton("Information about Flax", () => new AboutDialog().Show());
} }
private void InitWindowDecorations(RootControl mainWindow)
{
ScriptsBuilder.GetBinariesConfiguration(out _, out _, out _, out var configuration);
var driver = Platform.DisplayServer;
if (!string.IsNullOrEmpty(driver))
driver = $" ({driver})";
WindowDecorations = new MainWindowDecorations(mainWindow, !Utilities.Utils.UseCustomWindowDecorations(isMainWindow: true))
{
Parent = mainWindow,
IconTooltipText = $"{mainWindow.RootWindow.Title}\nVersion {Globals.EngineVersion}\nConfiguration {configuration}\nGraphics {GPUDevice.Instance.RendererType}{driver}",
};
}
private void OnOptionsChanged(EditorOptions options) private void OnOptionsChanged(EditorOptions options)
{ {
var inputOptions = options.Input; var inputOptions = options.Input;
@@ -1205,7 +1182,6 @@ namespace FlaxEditor.Modules
{ {
// Clear UI references (GUI cannot be used after window closing) // Clear UI references (GUI cannot be used after window closing)
MainMenu = null; MainMenu = null;
WindowDecorations = null;
ToolStrip = null; ToolStrip = null;
MasterPanel = null; MasterPanel = null;
StatusBar = null; StatusBar = null;

View File

@@ -10,6 +10,7 @@ using System.Text;
using System.Xml; using System.Xml;
using FlaxEditor.Content; using FlaxEditor.Content;
using FlaxEditor.GUI.Dialogs; using FlaxEditor.GUI.Dialogs;
using FlaxEditor.GUI.Docking;
using FlaxEditor.Windows; using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets; using FlaxEditor.Windows.Assets;
using FlaxEditor.Windows.Profiler; using FlaxEditor.Windows.Profiler;
@@ -757,19 +758,17 @@ namespace FlaxEditor.Modules
var settings = CreateWindowSettings.Default; var settings = CreateWindowSettings.Default;
settings.Title = "Flax Editor"; settings.Title = "Flax Editor";
settings.Size = Platform.DesktopSize * 0.75f; settings.Size = Platform.DesktopSize * 0.75f;
settings.MinimumSize = new Float2(200, 150);
settings.StartPosition = WindowStartPosition.CenterScreen; settings.StartPosition = WindowStartPosition.CenterScreen;
settings.ShowAfterFirstPaint = true; settings.ShowAfterFirstPaint = true;
#if PLATFORM_WINDOWS
if (Utilities.Utils.UseCustomWindowDecorations(isMainWindow: true)) if (!Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
{ {
settings.HasBorder = false; settings.HasBorder = false;
#if PLATFORM_WINDOWS && !PLATFORM_SDL
// Skip OS sizing frame and implement it using LeftButtonHit // Skip OS sizing frame and implement it using LeftButtonHit
settings.HasSizingFrame = false; settings.HasSizingFrame = false;
#endif
} }
#if PLATFORM_LINUX && !PLATFORM_SDL #elif PLATFORM_LINUX
settings.HasBorder = false; settings.HasBorder = false;
#endif #endif
MainWindow = Platform.CreateWindow(ref settings); MainWindow = Platform.CreateWindow(ref settings);
@@ -897,11 +896,9 @@ namespace FlaxEditor.Modules
if (type.IsAssignableTo(typeof(AssetEditorWindow))) if (type.IsAssignableTo(typeof(AssetEditorWindow)))
{ {
var ctor = type.GetConstructor(new Type[] { typeof(Editor), typeof(AssetItem) });
var assetItem = Editor.ContentDatabase.FindAsset(winData.AssetItemID); var assetItem = Editor.ContentDatabase.FindAsset(winData.AssetItemID);
var assetType = assetItem.GetType();
var ctor = type.GetConstructor(new Type[] { typeof(Editor), assetType });
var win = (AssetEditorWindow)ctor.Invoke(new object[] { Editor.Instance, assetItem }); 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); win.Show(winData.DockState, winData.DockState != DockState.Float ? winData.DockedTo : null, winData.SelectOnShow, winData.SplitterValue);
if (winData.DockState == DockState.Float) if (winData.DockState == DockState.Float)
{ {

View File

@@ -179,34 +179,6 @@ namespace FlaxEditor.Options
GameWindowThenRestore, GameWindowThenRestore,
} }
/// <summary>
/// Options for type of window decorations to use.
/// </summary>
public enum WindowDecorationsType
{
/// <summary>
/// Determined automatically based on the system and any known compatibility issues with native decorations.
/// </summary>
Auto,
/// <summary>
/// Automatically choose most compatible window decorations for child windows, prefer custom decorations on main window.
/// </summary>
[EditorDisplay(Name = "Auto (Child Only)")]
AutoChildOnly,
/// <summary>
/// Use native system window decorations on all windows.
/// </summary>
Native,
/// <summary>
/// Use custom client-side window decorations on all windows.
/// </summary>
[EditorDisplay(Name = "Client-side")]
ClientSide,
}
/// <summary> /// <summary>
/// Gets or sets the Editor User Interface scale. Applied to all UI elements, windows and text. Can be used to scale the interface up on a bigger display. Editor restart required. /// Gets or sets the Editor User Interface scale. Applied to all UI elements, windows and text. Can be used to scale the interface up on a bigger display. Editor restart required.
/// </summary> /// </summary>
@@ -296,14 +268,7 @@ namespace FlaxEditor.Options
[EditorDisplay("Interface"), EditorOrder(322)] [EditorDisplay("Interface"), EditorOrder(322)]
public bool ScrollToScriptOnAdd { get; set; } = true; public bool ScrollToScriptOnAdd { get; set; } = true;
#if PLATFORM_SDL #if PLATFORM_WINDOWS
/// <summary>
/// Gets or sets a value indicating whether use native window title bar decorations in child windows. Editor restart required.
/// </summary>
[DefaultValue(WindowDecorationsType.AutoChildOnly)]
[EditorDisplay("Interface"), EditorOrder(70), Tooltip("Determines whether use native window title bar decorations. Editor restart required.")]
public WindowDecorationsType WindowDecorations { get; set; } = WindowDecorationsType.AutoChildOnly;
#elif PLATFORM_WINDOWS
/// <summary> /// <summary>
/// Gets or sets a value indicating whether use native window title bar. Editor restart required. /// Gets or sets a value indicating whether use native window title bar. Editor restart required.
/// </summary> /// </summary>
@@ -312,7 +277,7 @@ namespace FlaxEditor.Options
public bool UseNativeWindowSystem { get; set; } = false; public bool UseNativeWindowSystem { get; set; } = false;
#endif #endif
#if PLATFORM_SDL || PLATFORM_WINDOWS #if PLATFORM_WINDOWS
/// <summary> /// <summary>
/// Gets or sets a value indicating whether a window containing a single tabs hides the tab bar. Editor restart recommended. /// Gets or sets a value indicating whether a window containing a single tabs hides the tab bar. Editor restart recommended.
/// </summary> /// </summary>

View File

@@ -36,8 +36,8 @@ namespace FlaxEditor.SceneGraph
} }
var center = _actor.Transform.Translation; var center = _actor.Transform.Translation;
ViewportIconsRenderer.GetBounds(center, ray.Ray.Position, out var sphere); ViewportIconsRenderer.GetBounds(ref center, ref ray.Ray.Position, out var sphere);
return CollisionsHelper.RayIntersectsSphere(ray.Ray, sphere, out distance); return CollisionsHelper.RayIntersectsSphere(ref ray.Ray, ref sphere, out distance);
} }
} }
} }

View File

@@ -109,10 +109,10 @@ namespace FlaxEditor.SceneGraph.Actors
// Skin vertex position with the current pose // Skin vertex position with the current pose
var position = positionStream.GetFloat3(j); var position = positionStream.GetFloat3(j);
Float3.Transform(position, skinningMatrices[indices[0]], out Float3 pos0); Float3.Transform(ref position, ref skinningMatrices[indices[0]], out Float3 pos0);
Float3.Transform(position, skinningMatrices[indices[1]], out Float3 pos1); Float3.Transform(ref position, ref skinningMatrices[indices[1]], out Float3 pos1);
Float3.Transform(position, skinningMatrices[indices[2]], out Float3 pos2); Float3.Transform(ref position, ref skinningMatrices[indices[2]], out Float3 pos2);
Float3.Transform(position, skinningMatrices[indices[3]], out Float3 pos3); Float3.Transform(ref position, ref skinningMatrices[indices[3]], out Float3 pos3);
position = pos0 * weights[0] + pos1 * weights[1] + pos2 * weights[2] + pos3 * weights[3]; position = pos0 * weights[0] + pos1 * weights[1] + pos2 * weights[2] + pos3 * weights[3];
// Add vertex to the bone list // Add vertex to the bone list
@@ -269,8 +269,8 @@ namespace FlaxEditor.SceneGraph.Actors
for (int i = 0; i < boneVertices.Count; i++) for (int i = 0; i < boneVertices.Count; i++)
{ {
var pos = boneTransform.WorldToLocal(boneVertices[i]); var pos = boneTransform.WorldToLocal(boneVertices[i]);
Vector3.Min(boneLocalBounds.Minimum, pos, out boneLocalBounds.Minimum); Vector3.Min(ref boneLocalBounds.Minimum, ref pos, out boneLocalBounds.Minimum);
Vector3.Max(boneLocalBounds.Maximum, pos, out boneLocalBounds.Maximum); Vector3.Max(ref boneLocalBounds.Maximum, ref pos, out boneLocalBounds.Maximum);
} }
// Add collision shape // Add collision shape
@@ -415,7 +415,7 @@ namespace FlaxEditor.SceneGraph.Actors
float bkLength = bk.Length; float bkLength = bk.Length;
if (bkLength > 0.0f) if (bkLength > 0.0f)
{ {
Float3.Transform(bk, matrix, out Float3 bkA); Float3.Transform(ref bk, ref matrix, out Float3 bkA);
bk = bkA / bkLength; bk = bkA / bkLength;
} }
} }

View File

@@ -184,7 +184,7 @@ namespace FlaxEditor.SceneGraph.Actors
/// <inheritdoc /> /// <inheritdoc />
public override bool RayCastSelf(ref RayCastData ray, out Real distance, out Vector3 normal) public override bool RayCastSelf(ref RayCastData ray, out Real distance, out Vector3 normal)
{ {
return Brush.Intersects(Index, ray.Ray, out distance, out normal); return Brush.Intersects(Index, ref ray.Ray, out distance, out normal);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -207,7 +207,7 @@ namespace FlaxEditor.SceneGraph.Actors
/// <inheritdoc /> /// <inheritdoc />
public override bool RayCastSelf(ref RayCastData ray, out Real distance, out Vector3 normal) public override bool RayCastSelf(ref RayCastData ray, out Real distance, out Vector3 normal)
{ {
if (((BoxBrush)_actor).OrientedBox.Intersects(ray.Ray)) if (((BoxBrush)_actor).OrientedBox.Intersects(ref ray.Ray))
{ {
for (int i = 0; i < ChildNodes.Count; i++) for (int i = 0; i < ChildNodes.Count; i++)
{ {

View File

@@ -107,7 +107,7 @@ namespace FlaxEditor.SceneGraph.Actors
{ {
normal = Vector3.Up; normal = Vector3.Up;
var sphere = new BoundingSphere(Transform.Translation, 10.0f); var sphere = new BoundingSphere(Transform.Translation, 10.0f);
return sphere.Intersects(ray.Ray, out distance); return sphere.Intersects(ref ray.Ray, out distance);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -56,7 +56,7 @@ namespace FlaxEditor.SceneGraph.Actors
return false; return false;
} }
return Camera.Internal_IntersectsItselfEditor(FlaxEngine.Object.GetUnmanagedPtr(_actor), ray.Ray, out distance); return Camera.Internal_IntersectsItselfEditor(FlaxEngine.Object.GetUnmanagedPtr(_actor), ref ray.Ray, out distance);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -58,7 +58,7 @@ namespace FlaxEditor.SceneGraph.Actors
public override Transform Transform public override Transform Transform
{ {
get => Actor.GetInstance(Index).Transform; get => Actor.GetInstance(Index).Transform;
set => Actor.SetInstanceTransform(Index, value); set => Actor.SetInstanceTransform(Index, ref value);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -63,7 +63,7 @@ namespace FlaxEditor.SceneGraph.Actors
{ {
normal = Vector3.Up; normal = Vector3.Up;
var sphere = new BoundingSphere(Transform.Translation, 10.0f); var sphere = new BoundingSphere(Transform.Translation, 10.0f);
return sphere.Intersects(ray.Ray, out distance); return sphere.Intersects(ref ray.Ray, out distance);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -177,7 +177,7 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = (Spline)_node.Actor; var actor = (Spline)_node.Actor;
var pos = actor.GetSplinePoint(Index); var pos = actor.GetSplinePoint(Index);
var nodeSize = NodeSizeByDistance(Transform.Translation, PointNodeSize, ray.View.Position); var nodeSize = NodeSizeByDistance(Transform.Translation, PointNodeSize, ray.View.Position);
return new BoundingSphere(pos, nodeSize).Intersects(ray.Ray, out distance); return new BoundingSphere(pos, nodeSize).Intersects(ref ray.Ray, out distance);
} }
public override void OnDebugDraw(ViewportDebugDrawData data) public override void OnDebugDraw(ViewportDebugDrawData data)
@@ -264,7 +264,7 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = (Spline)_node.Actor; var actor = (Spline)_node.Actor;
var pos = actor.GetSplineTangent(_index, _isIn).Translation; var pos = actor.GetSplineTangent(_index, _isIn).Translation;
var tangentSize = NodeSizeByDistance(Transform.Translation, TangentNodeSize, ray.View.Position); var tangentSize = NodeSizeByDistance(Transform.Translation, TangentNodeSize, ray.View.Position);
return new BoundingSphere(pos, tangentSize).Intersects(ray.Ray, out distance); return new BoundingSphere(pos, tangentSize).Intersects(ref ray.Ray, out distance);
} }
public override void OnDebugDraw(ViewportDebugDrawData data) public override void OnDebugDraw(ViewportDebugDrawData data)

View File

@@ -37,15 +37,15 @@ namespace FlaxEditor.SceneGraph.Actors
{ {
var up = Float3.Up; var up = Float3.Up;
Float3 translation = transform.Translation; Float3 translation = transform.Translation;
Matrix.Billboard(translation, viewPosition, up, viewDirection, out m2); Matrix.Billboard(ref translation, ref viewPosition, ref up, ref viewDirection, out m2);
Matrix.Multiply(m1, m2, out m3); Matrix.Multiply(ref m1, ref m2, out m3);
Matrix.Scaling(transform.Scale, out m1); Matrix.Scaling(ref transform.Scale, out m1);
Matrix.Multiply(m1, m3, out world); Matrix.Multiply(ref m1, ref m3, out world);
} }
else else
{ {
transform.GetWorld(out m2); transform.GetWorld(out m2);
Matrix.Multiply(m1, m2, out world); Matrix.Multiply(ref m1, ref m2, out world);
} }
OrientedBoundingBox bounds; OrientedBoundingBox bounds;
@@ -53,7 +53,7 @@ namespace FlaxEditor.SceneGraph.Actors
world.Decompose(out bounds.Transformation); world.Decompose(out bounds.Transformation);
normal = -ray.Ray.Direction; normal = -ray.Ray.Direction;
return bounds.Intersects(ray.Ray, out distance); return bounds.Intersects(ref ray.Ray, out distance);
} }
/// <inheritdoc /> /// <inheritdoc />

View File

@@ -96,7 +96,7 @@ namespace FlaxEditor.SceneGraph.Actors
for (int i = 0; i < verts.Length; i++) for (int i = 0; i < verts.Length; i++)
{ {
ref var v = ref verts[i]; ref var v = ref verts[i];
var distance = Float3.DistanceSquared(pointLocal, v); var distance = Float3.DistanceSquared(ref pointLocal, ref v);
if (distance <= minDistance) if (distance <= minDistance)
{ {
hit = true; hit = true;

View File

@@ -64,7 +64,7 @@ namespace FlaxEditor.SceneGraph.Actors
normal = Vector3.Up; normal = Vector3.Up;
if (Actor is UICanvas uiCanvas && uiCanvas.Is3D) if (Actor is UICanvas uiCanvas && uiCanvas.Is3D)
return uiCanvas.Bounds.Intersects(ray.Ray, out distance); return uiCanvas.Bounds.Intersects(ref ray.Ray, out distance);
distance = 0; distance = 0;
return false; return false;

View File

@@ -352,7 +352,7 @@ namespace FlaxEditor.SceneGraph
for (int i = 0; i < ChildNodes.Count; i++) for (int i = 0; i < ChildNodes.Count; i++)
{ {
ChildNodes[i].GetEditorSphere(out var childSphere); ChildNodes[i].GetEditorSphere(out var childSphere);
BoundingSphere.Merge(sphere, childSphere, out sphere); BoundingSphere.Merge(ref sphere, ref childSphere, out sphere);
} }
} }

View File

@@ -6,6 +6,7 @@
#include "ScriptsBuilder.h" #include "ScriptsBuilder.h"
#include "CodeEditors/VisualStudioCodeEditor.h" #include "CodeEditors/VisualStudioCodeEditor.h"
#include "CodeEditors/RiderCodeEditor.h" #include "CodeEditors/RiderCodeEditor.h"
#include "CodeEditors/ZedEditor.h"
#if USE_VISUAL_STUDIO_DTE #if USE_VISUAL_STUDIO_DTE
#include "CodeEditors/VisualStudio/VisualStudioEditor.h" #include "CodeEditors/VisualStudio/VisualStudioEditor.h"
#endif #endif
@@ -139,34 +140,6 @@ CodeEditor* CodeEditingManager::GetCodeEditor(CodeEditorTypes editorType)
return nullptr; return nullptr;
} }
String CodeEditingManager::GetName(CodeEditorTypes editorType)
{
const auto editor = GetCodeEditor(editorType);
if (editor)
{
return editor->GetName();
}
else
{
LOG(Warning, "Missing code editor type {0}", (int32)editorType);
return String::Empty;
}
}
String CodeEditingManager::GetGenerateProjectCustomArgs(CodeEditorTypes editorType)
{
const auto editor = GetCodeEditor(editorType);
if (editor)
{
return editor->GetGenerateProjectCustomArgs();
}
else
{
LOG(Warning, "Missing code editor type {0}", (int32)editorType);
return String::Empty;
}
}
void CodeEditingManager::OpenFile(CodeEditorTypes editorType, const String& path, int32 line) void CodeEditingManager::OpenFile(CodeEditorTypes editorType, const String& path, int32 line)
{ {
const auto editor = GetCodeEditor(editorType); const auto editor = GetCodeEditor(editorType);
@@ -269,6 +242,7 @@ bool CodeEditingManagerService::Init()
#endif #endif
VisualStudioCodeEditor::FindEditors(&CodeEditors); VisualStudioCodeEditor::FindEditors(&CodeEditors);
RiderCodeEditor::FindEditors(&CodeEditors); RiderCodeEditor::FindEditors(&CodeEditors);
ZedEditor::FindEditors(&CodeEditors);
CodeEditors.Add(New<SystemDefaultCodeEditor>()); CodeEditors.Add(New<SystemDefaultCodeEditor>());
return false; return false;

View File

@@ -77,6 +77,11 @@ API_ENUM(Namespace="FlaxEditor", Attributes="HideInEditor") enum class CodeEdito
/// </summary> /// </summary>
VSCodeInsiders, VSCodeInsiders,
/// <summary>
/// Zed
/// </summary>
Zed,
/// <summary> /// <summary>
/// Rider /// Rider
/// </summary> /// </summary>
@@ -109,18 +114,9 @@ public:
/// <summary> /// <summary>
/// Gets the name of the editor. /// Gets the name of the editor.
/// </summary> /// </summary>
/// <returns>The name.</returns> /// <returns>The name</returns>
virtual String GetName() const = 0; virtual String GetName() const = 0;
/// <summary>
/// Gets the custom arguments for the Flax.Build tool to add when generating project files for this code editor.
/// </summary>
/// <returns>The custom arguments to generate project files.</returns>
virtual String GetGenerateProjectCustomArgs() const
{
return String::Empty;
}
/// <summary> /// <summary>
/// Opens the file. /// Opens the file.
/// </summary> /// </summary>
@@ -178,20 +174,6 @@ public:
/// <returns>The editor object or null if not found.</returns> /// <returns>The editor object or null if not found.</returns>
static CodeEditor* GetCodeEditor(CodeEditorTypes editorType); static CodeEditor* GetCodeEditor(CodeEditorTypes editorType);
/// <summary>
/// Gets the name of the editor.
/// </summary>
/// <param name="editorType">The code editor type.</param>
/// <returns>The name.</returns>
API_FUNCTION() static String GetName(CodeEditorTypes editorType);
/// <summary>
/// Gets the custom arguments for the Flax.Build tool to add when generating project files for this code editor.
/// </summary>
/// <param name="editorType">The code editor type.</param>
/// <returns>The custom arguments to generate project files.</returns>
API_FUNCTION() static String GetGenerateProjectCustomArgs(CodeEditorTypes editorType);
/// <summary> /// <summary>
/// Opens the file. Handles async opening. /// Opens the file. Handles async opening.
/// </summary> /// </summary>

View File

@@ -14,6 +14,9 @@
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS
#include "Engine/Platform/Win32/IncludeWindowsHeaders.h" #include "Engine/Platform/Win32/IncludeWindowsHeaders.h"
#elif PLATFORM_MAC
#include "Engine/Platform/Apple/AppleUtils.h"
#include <AppKit/AppKit.h>
#endif #endif
namespace namespace
@@ -218,6 +221,15 @@ void RiderCodeEditor::FindEditors(Array<CodeEditor*>* output)
#endif #endif
#if PLATFORM_MAC #if PLATFORM_MAC
// System installed app
NSURL* AppURL = [[NSWorkspace sharedWorkspace]URLForApplicationWithBundleIdentifier:@"com.jetbrains.rider"];
if (AppURL != nullptr)
{
const String path = AppleUtils::ToString((CFStringRef)[AppURL path]);
SearchDirectory(&installations, path / TEXT("/Contents/Resources"));
}
// JetBrains Toolbox installations
String applicationSupportFolder; String applicationSupportFolder;
FileSystem::GetSpecialFolderPath(SpecialFolder::ProgramData, applicationSupportFolder); FileSystem::GetSpecialFolderPath(SpecialFolder::ProgramData, applicationSupportFolder);
@@ -232,6 +244,7 @@ void RiderCodeEditor::FindEditors(Array<CodeEditor*>* output)
// Check the local installer version // Check the local installer version
SearchDirectory(&installations, TEXT("/Applications/Rider.app/Contents/Resources")); SearchDirectory(&installations, TEXT("/Applications/Rider.app/Contents/Resources"));
SearchDirectory(&installations, TEXT("/Applications/Rider EAP.app/Contents/Resources"));
#endif #endif
for (const String& directory : subDirectories) for (const String& directory : subDirectories)
@@ -257,17 +270,12 @@ String RiderCodeEditor::GetName() const
return TEXT("Rider"); return TEXT("Rider");
} }
String RiderCodeEditor::GetGenerateProjectCustomArgs() const
{
return TEXT("-vs2022");
}
void RiderCodeEditor::OpenFile(const String& path, int32 line) void RiderCodeEditor::OpenFile(const String& path, int32 line)
{ {
// Generate project files if solution is missing // Generate project files if solution is missing
if (!FileSystem::FileExists(_solutionPath)) if (!FileSystem::FileExists(_solutionPath))
{ {
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs()); ScriptsBuilder::GenerateProject(TEXT("-vs2022"));
} }
// Open file // Open file
@@ -295,7 +303,7 @@ void RiderCodeEditor::OpenSolution()
// Generate project files if solution is missing // Generate project files if solution is missing
if (!FileSystem::FileExists(_solutionPath)) if (!FileSystem::FileExists(_solutionPath))
{ {
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs()); ScriptsBuilder::GenerateProject(TEXT("-vs2022"));
} }
// Open solution // Open solution
@@ -317,5 +325,5 @@ void RiderCodeEditor::OpenSolution()
void RiderCodeEditor::OnFileAdded(const String& path) void RiderCodeEditor::OnFileAdded(const String& path)
{ {
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs()); ScriptsBuilder::GenerateProject();
} }

View File

@@ -35,7 +35,6 @@ public:
// [CodeEditor] // [CodeEditor]
CodeEditorTypes GetType() const override; CodeEditorTypes GetType() const override;
String GetName() const override; String GetName() const override;
String GetGenerateProjectCustomArgs() const override;
void OpenFile(const String& path, int32 line) override; void OpenFile(const String& path, int32 line) override;
void OpenSolution() override; void OpenSolution() override;
void OnFileAdded(const String& path) override; void OnFileAdded(const String& path) override;

View File

@@ -148,17 +148,12 @@ String VisualStudioEditor::GetName() const
return String(ToString(_version)); return String(ToString(_version));
} }
String VisualStudioEditor::GetGenerateProjectCustomArgs() const
{
return String::Format(TEXT("-{0}"), String(ToString(_version)).ToLower());
}
void VisualStudioEditor::OpenFile(const String& path, int32 line) void VisualStudioEditor::OpenFile(const String& path, int32 line)
{ {
// Generate project files if solution is missing // Generate project files if solution is missing
if (!FileSystem::FileExists(_solutionPath)) if (!FileSystem::FileExists(_solutionPath))
{ {
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs()); ScriptsBuilder::GenerateProject();
} }
// Open file // Open file
@@ -177,7 +172,7 @@ void VisualStudioEditor::OpenSolution()
// Generate project files if solution is missing // Generate project files if solution is missing
if (!FileSystem::FileExists(_solutionPath)) if (!FileSystem::FileExists(_solutionPath))
{ {
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs()); ScriptsBuilder::GenerateProject();
} }
// Open solution // Open solution
@@ -192,7 +187,7 @@ void VisualStudioEditor::OpenSolution()
void VisualStudioEditor::OnFileAdded(const String& path) void VisualStudioEditor::OnFileAdded(const String& path)
{ {
// TODO: finish dynamic files adding to the project - for now just regenerate it // TODO: finish dynamic files adding to the project - for now just regenerate it
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs()); ScriptsBuilder::GenerateProject();
return; return;
if (!FileSystem::FileExists(_solutionPath)) if (!FileSystem::FileExists(_solutionPath))
{ {

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