4 Commits

Author SHA1 Message Date
824ff7050e Fix managed wrapper function parameter handling for BytesContainer
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-12-23 01:41:01 +02:00
042843fe42 Fix clang bindings code generation for non-const ref parameters
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-12-20 23:04:08 +02:00
8631b389c1 asdf 2025-12-20 23:02:42 +02:00
e3f5af530b Fix incorrect class namespace in bindings class name lookups 2025-12-19 23:57:41 +02:00
521 changed files with 5057 additions and 106227 deletions

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

View File

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

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

@@ -139,7 +139,7 @@ namespace FlaxEditor.CustomEditors
return new GenericEditor(); return new GenericEditor();
} }
[LibraryImport("FlaxEngine", EntryPoint = "CustomEditorsUtilInternal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "CustomEditorsUtilInternal_GetCustomEditor", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalUsing(typeof(SystemTypeMarshaller))] [return: MarshalUsing(typeof(SystemTypeMarshaller))]
internal static partial Type Internal_GetCustomEditor([MarshalUsing(typeof(SystemTypeMarshaller))] Type targetType); internal static partial Type Internal_GetCustomEditor([MarshalUsing(typeof(SystemTypeMarshaller))] Type targetType);
} }

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

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

@@ -192,7 +192,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 +206,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();

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

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

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

@@ -69,18 +69,18 @@ namespace FlaxEditor
/// <summary> /// <summary>
/// Gets a value indicating whether this Editor is running a dev instance of the engine. /// Gets a value indicating whether this Editor is running a dev instance of the engine.
/// </summary> /// </summary>
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsDevInstance")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsDevInstance", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool IsDevInstance(); internal static partial bool IsDevInstance();
/// <summary> /// <summary>
/// Gets a value indicating whether this Editor is running as official build (distributed via Flax services). /// Gets a value indicating whether this Editor is running as official build (distributed via Flax services).
/// </summary> /// </summary>
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsOfficialBuild")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsOfficialBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool IsOfficialBuild(); internal static partial bool IsOfficialBuild();
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsPlayMode")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_IsPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_IsPlayMode(); internal static partial bool Internal_IsPlayMode();
@@ -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);
@@ -1647,103 +1647,96 @@ namespace FlaxEditor
} }
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ReadOutputLogs", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_ReadOutputLogs", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
internal static partial int Internal_ReadOutputLogs([MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<string, FlaxEngine.Interop.NativeString>), CountElementName = "outCapacity")] ref string[] outMessages, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 3)] ref byte[] outLogTypes, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I8, SizeParamIndex = 3)] ref long[] outLogTimes, int outCapacity); internal static partial int Internal_ReadOutputLogs([MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref string[] outMessages, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref byte[] outLogTypes, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "outCapacity")] ref long[] outLogTimes, int outCapacity);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetPlayMode")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetPlayMode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
internal static partial void Internal_SetPlayMode([MarshalAs(UnmanagedType.U1)] bool value); internal static partial void Internal_SetPlayMode([MarshalAs(UnmanagedType.U1)] bool value);
internal static string Internal_GetProjectPath() [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
{ internal static partial string Internal_GetProjectPath();
Internal_GetProjectPath(out string projectPath);
return projectPath;
}
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetProjectPath", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_GetProjectPath([MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller))] out string projectPath);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloneAssetFile", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_CloneAssetFile(string dstPath, string srcPath, ref Guid dstId); internal static partial bool Internal_CloneAssetFile(string dstPath, string srcPath, ref Guid dstId);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAudioClipMetadata")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAudioClipMetadata", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_GetAudioClipMetadata(IntPtr obj, out int originalSize, out int importedSize); internal static partial void Internal_GetAudioClipMetadata(IntPtr obj, out int originalSize, out int importedSize);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SaveJsonAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_SaveJsonAsset(string outputPath, string data, string typename); internal static partial bool Internal_SaveJsonAsset(string outputPath, string data, string typename);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CopyCache")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CopyCache", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_CopyCache(ref Guid dstId, ref Guid srcId); internal static partial void Internal_CopyCache(ref Guid dstId, ref Guid srcId);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_BakeLightmaps")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_BakeLightmaps", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_BakeLightmaps([MarshalAs(UnmanagedType.U1)] bool cancel); internal static partial void Internal_BakeLightmaps([MarshalAs(UnmanagedType.U1)] bool cancel);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetShaderAssetSourceCode", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalUsing(typeof(FlaxEngine.Interop.StringViewMarshaller))]
internal static partial string Internal_GetShaderAssetSourceCode(IntPtr obj); internal static partial string Internal_GetShaderAssetSourceCode(IntPtr obj);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CookMeshCollision", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_CookMeshCollision(string path, CollisionDataType type, IntPtr model, int modelLodIndex, uint materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int convexVertexLimit); internal static partial bool Internal_CookMeshCollision(string path, CollisionDataType type, IntPtr model, int modelLodIndex, uint materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int convexVertexLimit);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetCollisionWires")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetCollisionWires", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_GetCollisionWires(IntPtr collisionData, [MarshalUsing(typeof(FlaxEngine.Interop.NativeArrayMarshaller<,>), CountElementName = "trianglesCount")] out Float3[] triangles, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "indicesCount")] out int[] indices, out int trianglesCount, out int indicesCount); internal static partial void Internal_GetCollisionWires(IntPtr collisionData, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "trianglesCount")] out Float3[] triangles, [MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "indicesCount")] out int[] indices, out int trianglesCount, out int indicesCount);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetEditorBoxWithChildren")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetEditorBoxWithChildren", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_GetEditorBoxWithChildren(IntPtr obj, out BoundingBox resultAsRef); internal static partial void Internal_GetEditorBoxWithChildren(IntPtr obj, out BoundingBox resultAsRef);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetOptions")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetOptions", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_SetOptions(ref InternalOptions options); internal static partial void Internal_SetOptions(ref InternalOptions options);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DrawNavMesh")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DrawNavMesh", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_DrawNavMesh(); internal static partial void Internal_DrawNavMesh();
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloseSplashScreen")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CloseSplashScreen", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_CloseSplashScreen(); internal static partial void Internal_CloseSplashScreen();
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CreateVisualScript", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_CreateVisualScript(string outputPath, string baseTypename); internal static partial bool Internal_CreateVisualScript(string outputPath, string baseTypename);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanImport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial string Internal_CanImport(string extension); internal static partial string Internal_CanImport(string extension);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanExport", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_CanExport(string path); internal static partial bool Internal_CanExport(string path);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_Export", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_Export(string inputPath, string outputFolder); internal static partial bool Internal_Export(string inputPath, string outputFolder);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsEveryAssemblyLoaded")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsEveryAssemblyLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_GetIsEveryAssemblyLoaded(); internal static partial bool Internal_GetIsEveryAssemblyLoaded();
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetLastProjectOpenedEngineBuild")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetLastProjectOpenedEngineBuild", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial int Internal_GetLastProjectOpenedEngineBuild(); internal static partial int Internal_GetLastProjectOpenedEngineBuild();
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsCSGActive")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetIsCSGActive", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_GetIsCSGActive(); internal static partial bool Internal_GetIsCSGActive();
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_RunVisualScriptBreakpointLoopTick")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_RunVisualScriptBreakpointLoopTick", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime); internal static partial void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_DeserializeSceneObject(IntPtr sceneObject, string json); internal static partial void Internal_DeserializeSceneObject(IntPtr sceneObject, string json);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_LoadAsset")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_LoadAsset", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_LoadAsset(ref Guid id); internal static partial void Internal_LoadAsset(ref Guid id);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanSetToRoot")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_CanSetToRoot", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[return: MarshalAs(UnmanagedType.U1)] [return: MarshalAs(UnmanagedType.U1)]
internal static partial bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot); internal static partial bool Internal_CanSetToRoot(IntPtr prefab, IntPtr newRoot);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial float Internal_GetAnimationTime(IntPtr animatedModel); internal static partial float Internal_GetAnimationTime(IntPtr animatedModel);
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetAnimationTime")] [LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_SetAnimationTime", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
internal static partial void Internal_SetAnimationTime(IntPtr animatedModel, float time); internal static partial void Internal_SetAnimationTime(IntPtr animatedModel, float time);
#endregion #endregion

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

@@ -58,22 +58,22 @@ void OnLogMessage(LogType type, const StringView& msg)
{ {
ScopeLock lock(CachedLogDataLocker); ScopeLock lock(CachedLogDataLocker);
CachedLogData.EnsureCapacity(sizeof(int32) + sizeof(DateTime) + sizeof(int32) + msg.Length() * sizeof(Char)); CachedLogData.EnsureCapacity(4 + 8 + 4 + msg.Length() * 2);
// Log Type // Log Type
int32 buf = (int32)type; int32 buf = (int32)type;
CachedLogData.Add((byte*)&buf, sizeof(int32)); CachedLogData.Add((byte*)&buf, 4);
// Time // Time
auto time = DateTime::Now(); auto time = DateTime::Now();
CachedLogData.Add((byte*)&time.Ticks, sizeof(DateTime)); CachedLogData.Add((byte*)&time.Ticks, 8);
// Message Length // Message Length
buf = msg.Length(); buf = msg.Length();
CachedLogData.Add((byte*)&buf, sizeof(int32)); CachedLogData.Add((byte*)&buf, 4);
// Message // Message
CachedLogData.Add((byte*)msg.Get(), msg.Length() * sizeof(Char)); CachedLogData.Add((byte*)msg.Get(), msg.Length() * 2);
} }
DEFINE_INTERNAL_CALL(bool) EditorInternal_IsDevInstance() DEFINE_INTERNAL_CALL(bool) EditorInternal_IsDevInstance()
@@ -99,7 +99,7 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_IsPlayMode()
return Editor::IsPlayMode; return Editor::IsPlayMode;
} }
DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(NativeArray<String>* outMessages, NativeArray<byte>* outLogTypes, NativeArray<int64>* outLogTimes, int outArraySize) DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(MArray** outMessages, MArray** outLogTypes, MArray** outLogTimes, int outArraySize)
{ {
ScopeLock lock(CachedLogDataLocker); ScopeLock lock(CachedLogDataLocker);
if (CachedLogData.IsEmpty() || CachedLogData.Get() == nullptr) if (CachedLogData.IsEmpty() || CachedLogData.Get() == nullptr)
@@ -108,30 +108,27 @@ DEFINE_INTERNAL_CALL(int32) EditorInternal_ReadOutputLogs(NativeArray<String>* o
int32 count = 0; int32 count = 0;
const int32 maxCount = outArraySize; const int32 maxCount = outArraySize;
String* messages = &outMessages->data[0];
byte* ptr = CachedLogData.Get(); byte* ptr = CachedLogData.Get();
byte* end = ptr + CachedLogData.Count(); byte* end = ptr + CachedLogData.Count();
byte* outLogTypesPtr = outLogTypes->data; byte* outLogTypesPtr = MCore::Array::GetAddress<byte>(*outLogTypes);
int64* outLogTimesPtr = outLogTimes->data; int64* outLogTimesPtr = MCore::Array::GetAddress<int64>(*outLogTimes);
while (count < maxCount && ptr != end) while (count < maxCount && ptr != end)
{ {
auto type = (byte)*(int32*)ptr; auto type = (byte)*(int32*)ptr;
ptr += sizeof(int32); ptr += 4;
auto time = *(int64*)ptr; auto time = *(int64*)ptr;
ptr += sizeof(int64); ptr += 8;
auto length = *(int32*)ptr; auto length = *(int32*)ptr;
ptr += sizeof(int32); ptr += 4;
auto msg = (Char*)ptr; auto msg = (Char*)ptr;
ptr += length * sizeof(Char); ptr += length * 2;
auto msgObj = String(msg, length); auto msgObj = MUtils::ToString(StringView(msg, length));
String& str = messages[count]; MCore::GC::WriteArrayRef(*outMessages, (MObject*)msgObj, count);
ASSERT(str.Get() == nullptr && str.Length() == 0);
str = msgObj;
outLogTypesPtr[count] = type; outLogTypesPtr[count] = type;
outLogTimesPtr[count] = time; outLogTimesPtr[count] = time;
@@ -150,9 +147,9 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_SetPlayMode(bool value)
Editor::IsPlayMode = value; Editor::IsPlayMode = value;
} }
DEFINE_INTERNAL_CALL(void) EditorInternal_GetProjectPath(StringView* projectPath) DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetProjectPath()
{ {
*projectPath = Editor::Project->ProjectPath; return MUtils::ToString(Editor::Project->ProjectPath);
} }
DEFINE_INTERNAL_CALL(void) EditorInternal_CloseSplashScreen() DEFINE_INTERNAL_CALL(void) EditorInternal_CloseSplashScreen()
@@ -162,7 +159,6 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_CloseSplashScreen()
DEFINE_INTERNAL_CALL(bool) EditorInternal_CloneAssetFile(MString* dstPathObj, MString* srcPathObj, Guid* dstId) DEFINE_INTERNAL_CALL(bool) EditorInternal_CloneAssetFile(MString* dstPathObj, MString* srcPathObj, Guid* dstId)
{ {
PLATFORM_DEBUG_BREAK;
// Get normalized paths // Get normalized paths
String dstPath, srcPath; String dstPath, srcPath;
MUtils::ToString(dstPathObj, dstPath); MUtils::ToString(dstPathObj, dstPath);
@@ -176,7 +172,6 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CloneAssetFile(MString* dstPathObj, MS
DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MString* outputPathObj, MString* baseTypenameObj) DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MString* outputPathObj, MString* baseTypenameObj)
{ {
PLATFORM_DEBUG_BREAK;
String outputPath; String outputPath;
MUtils::ToString(outputPathObj, outputPath); MUtils::ToString(outputPathObj, outputPath);
FileSystem::NormalizePath(outputPath); FileSystem::NormalizePath(outputPath);
@@ -187,7 +182,6 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CreateVisualScript(MString* outputPath
DEFINE_INTERNAL_CALL(MString*) EditorInternal_CanImport(MString* extensionObj) DEFINE_INTERNAL_CALL(MString*) EditorInternal_CanImport(MString* extensionObj)
{ {
PLATFORM_DEBUG_BREAK;
String extension; String extension;
MUtils::ToString(extensionObj, extension); MUtils::ToString(extensionObj, extension);
if (extension.Length() > 0 && extension[0] == '.') if (extension.Length() > 0 && extension[0] == '.')
@@ -205,7 +199,6 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_GetAudioClipMetadata(AudioClip* clip,
DEFINE_INTERNAL_CALL(bool) EditorInternal_SaveJsonAsset(MString* outputPathObj, MString* dataObj, MString* dataTypeNameObj) DEFINE_INTERNAL_CALL(bool) EditorInternal_SaveJsonAsset(MString* outputPathObj, MString* dataObj, MString* dataTypeNameObj)
{ {
PLATFORM_DEBUG_BREAK;
String outputPath; String outputPath;
MUtils::ToString(outputPathObj, outputPath); MUtils::ToString(outputPathObj, outputPath);
FileSystem::NormalizePath(outputPath); FileSystem::NormalizePath(outputPath);
@@ -223,7 +216,6 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_SaveJsonAsset(MString* outputPathObj,
DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MString* pathObj) DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MString* pathObj)
{ {
PLATFORM_DEBUG_BREAK;
#if COMPILE_WITH_ASSETS_EXPORTER #if COMPILE_WITH_ASSETS_EXPORTER
String path; String path;
MUtils::ToString(pathObj, path); MUtils::ToString(pathObj, path);
@@ -237,7 +229,6 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanExport(MString* pathObj)
DEFINE_INTERNAL_CALL(bool) EditorInternal_Export(MString* inputPathObj, MString* outputFolderObj) DEFINE_INTERNAL_CALL(bool) EditorInternal_Export(MString* inputPathObj, MString* outputFolderObj)
{ {
PLATFORM_DEBUG_BREAK;
#if COMPILE_WITH_ASSETS_EXPORTER #if COMPILE_WITH_ASSETS_EXPORTER
String inputPath; String inputPath;
MUtils::ToString(inputPathObj, inputPath); MUtils::ToString(inputPathObj, inputPath);
@@ -255,7 +246,6 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_Export(MString* inputPathObj, MString*
DEFINE_INTERNAL_CALL(void) EditorInternal_CopyCache(Guid* dstId, Guid* srcId) DEFINE_INTERNAL_CALL(void) EditorInternal_CopyCache(Guid* dstId, Guid* srcId)
{ {
PLATFORM_DEBUG_BREAK;
ShaderCacheManager::CopyCache(*dstId, *srcId); ShaderCacheManager::CopyCache(*dstId, *srcId);
} }
@@ -270,7 +260,6 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_BakeLightmaps(bool cancel)
DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetShaderAssetSourceCode(BinaryAsset* obj) DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetShaderAssetSourceCode(BinaryAsset* obj)
{ {
PLATFORM_DEBUG_BREAK;
INTERNAL_CALL_CHECK_RETURN(obj, nullptr); INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
if (obj->WaitForLoaded()) if (obj->WaitForLoaded())
DebugLog::ThrowNullReference(); DebugLog::ThrowNullReference();
@@ -298,7 +287,6 @@ DEFINE_INTERNAL_CALL(MString*) EditorInternal_GetShaderAssetSourceCode(BinaryAss
DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit) DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MString* pathObj, CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit)
{ {
PLATFORM_DEBUG_BREAK;
#if COMPILE_WITH_PHYSICS_COOKING #if COMPILE_WITH_PHYSICS_COOKING
CollisionCooking::Argument arg; CollisionCooking::Argument arg;
String path; String path;
@@ -319,7 +307,6 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CookMeshCollision(MString* pathObj, Co
DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* collisionData, MArray** triangles, MArray** indices, int* trianglesCount, int* indicesCount) DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* collisionData, MArray** triangles, MArray** indices, int* trianglesCount, int* indicesCount)
{ {
PLATFORM_DEBUG_BREAK;
if (!collisionData || collisionData->WaitForLoaded() || collisionData->GetOptions().Type == CollisionDataType::None) if (!collisionData || collisionData->WaitForLoaded() || collisionData->GetOptions().Type == CollisionDataType::None)
return; return;
@@ -345,7 +332,6 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_GetCollisionWires(CollisionData* colli
DEFINE_INTERNAL_CALL(void) EditorInternal_GetEditorBoxWithChildren(Actor* obj, BoundingBox* result) DEFINE_INTERNAL_CALL(void) EditorInternal_GetEditorBoxWithChildren(Actor* obj, BoundingBox* result)
{ {
PLATFORM_DEBUG_BREAK;
INTERNAL_CALL_CHECK(obj); INTERNAL_CALL_CHECK(obj);
*result = obj->GetEditorBoxChildren(); *result = obj->GetEditorBoxChildren();
} }
@@ -416,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)
{ {
@@ -450,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;
@@ -475,7 +458,6 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa
DEFINE_INTERNAL_CALL(void) EditorInternal_DeserializeSceneObject(SceneObject* sceneObject, MString* jsonObj) DEFINE_INTERNAL_CALL(void) EditorInternal_DeserializeSceneObject(SceneObject* sceneObject, MString* jsonObj)
{ {
PLATFORM_DEBUG_BREAK;
PROFILE_CPU_NAMED("DeserializeSceneObject"); PROFILE_CPU_NAMED("DeserializeSceneObject");
StringAnsi json; StringAnsi json;
@@ -546,9 +528,10 @@ DEFINE_INTERNAL_CALL(MTypeObject*) CustomEditorsUtilInternal_GetCustomEditor(MTy
return CustomEditorsUtil::GetCustomEditor(targetType); return CustomEditorsUtil::GetCustomEditor(targetType);
} }
DEFINE_INTERNAL_CALL(NativeSpan<String>) LayersAndTagsSettingsInternal_GetCurrentLayers() DEFINE_INTERNAL_CALL(MArray*) LayersAndTagsSettingsInternal_GetCurrentLayers(int* layersCount)
{ {
return NativeSpan<String>::AsSpan(Level::Layers, Math::Max(1, Level::GetNonEmptyLayerNamesCount())); *layersCount = Math::Max(1, Level::GetNonEmptyLayerNamesCount());
return MUtils::ToArray(Span<String>(Level::Layers, *layersCount));
} }
DEFINE_INTERNAL_CALL(void) GameSettingsInternal_Apply() DEFINE_INTERNAL_CALL(void) GameSettingsInternal_Apply()

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

@@ -41,9 +41,9 @@ namespace FlaxEditor.Modules.SourceCodeEditing
var vsCode = codeEditing.GetInBuildEditor(CodeEditorTypes.VSCode); var vsCode = codeEditing.GetInBuildEditor(CodeEditorTypes.VSCode);
var rider = codeEditing.GetInBuildEditor(CodeEditorTypes.Rider); var rider = codeEditing.GetInBuildEditor(CodeEditorTypes.Rider);
#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.VS2019; i >= (int)CodeEditorTypes.VS2008; i--)
{ {
var visualStudio = codeEditing.GetInBuildEditor((CodeEditorTypes)i); var visualStudio = codeEditing.GetInBuildEditor((CodeEditorTypes)i);
if (visualStudio != null) if (visualStudio != null)
@@ -74,7 +74,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,71 @@ 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;
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";
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;
@@ -771,20 +763,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 +1183,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);

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

@@ -139,34 +139,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);

View File

@@ -109,18 +109,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 +169,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

@@ -257,17 +257,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 +290,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 +312,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))
{ {

View File

@@ -56,7 +56,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

@@ -128,11 +128,6 @@ String VisualStudioCodeEditor::GetName() const
return _isInsiders ? TEXT("Visual Studio Code - Insiders") : TEXT("Visual Studio Code"); return _isInsiders ? TEXT("Visual Studio Code - Insiders") : TEXT("Visual Studio Code");
} }
String VisualStudioCodeEditor::GetGenerateProjectCustomArgs() const
{
return TEXT("-vs2022 -vscode");
}
void VisualStudioCodeEditor::OpenFile(const String& path, int32 line) void VisualStudioCodeEditor::OpenFile(const String& path, int32 line)
{ {
// Generate VS solution files for intellisense // Generate VS solution files for intellisense

View File

@@ -37,7 +37,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;
bool UseAsyncForOpen() const override; bool UseAsyncForOpen() const override;

View File

@@ -121,13 +121,9 @@ void ScriptsBuilderImpl::sourceDirEvent(const String& path, FileSystemAction act
// Discard non-source files or generated files // Discard non-source files or generated files
if ((!path.EndsWith(TEXT(".cs")) && if ((!path.EndsWith(TEXT(".cs")) &&
!path.EndsWith(TEXT(".cpp")) && !path.EndsWith(TEXT(".cpp")) &&
!path.EndsWith(TEXT(".c")) &&
!path.EndsWith(TEXT(".hpp")) &&
!path.EndsWith(TEXT(".h"))) || !path.EndsWith(TEXT(".h"))) ||
path.EndsWith(TEXT(".Gen.cs"))) path.EndsWith(TEXT(".Gen.cs")))
{
return; return;
}
ScopeLock scopeLock(_locker); ScopeLock scopeLock(_locker);
_lastSourceCodeEdited = DateTime::Now(); _lastSourceCodeEdited = DateTime::Now();

View File

@@ -479,7 +479,7 @@ namespace FlaxEditor.Surface.Archetypes
// Scale debug pointer when it moves to make it more visible when investigating blending // Scale debug pointer when it moves to make it more visible when investigating blending
const float debugMaxSize = 2.0f; const float debugMaxSize = 2.0f;
float debugScale = Mathf.Saturate(Float2.Distance(_debugPos, prev) / new Float2(_rangeX.Absolute.ValuesSum, _rangeY.Absolute.ValuesSum).Length * 100.0f) * debugMaxSize + 1.0f; float debugScale = Mathf.Saturate(Float2.Distance(ref _debugPos, ref prev) / new Float2(_rangeX.Absolute.ValuesSum, _rangeY.Absolute.ValuesSum).Length * 100.0f) * debugMaxSize + 1.0f;
float debugBlendSpeed = _debugScale <= debugScale ? 4.0f : 1.0f; float debugBlendSpeed = _debugScale <= debugScale ? 4.0f : 1.0f;
_debugScale = Mathf.Lerp(_debugScale, debugScale, deltaTime * debugBlendSpeed); _debugScale = Mathf.Lerp(_debugScale, debugScale, deltaTime * debugBlendSpeed);
} }
@@ -1189,9 +1189,9 @@ namespace FlaxEditor.Surface.Archetypes
_triangleColors = new Color[_triangles.Length]; _triangleColors = new Color[_triangles.Length];
for (int i = 0; i < _triangles.Length; i += 3) for (int i = 0; i < _triangles.Length; i += 3)
{ {
var is0 = Float2.NearEqual(_triangles[i + 0], pos); var is0 = Float2.NearEqual(ref _triangles[i + 0], ref pos);
var is1 = Float2.NearEqual(_triangles[i + 1], pos); var is1 = Float2.NearEqual(ref _triangles[i + 1], ref pos);
var is2 = Float2.NearEqual(_triangles[i + 2], pos); var is2 = Float2.NearEqual(ref _triangles[i + 2], ref pos);
if (is0 || is1 || is2) if (is0 || is1 || is2)
{ {
selectedTriangles.Add(_triangles[i + 0]); selectedTriangles.Add(_triangles[i + 0]);
@@ -1233,7 +1233,7 @@ namespace FlaxEditor.Surface.Archetypes
if (point != null) if (point != null)
{ {
var highlightColor = point.IsMouseDown ? style.SelectionBorder : style.BackgroundSelected; var highlightColor = point.IsMouseDown ? style.SelectionBorder : style.BackgroundSelected;
Render2D.PushTint(highlightColor); Render2D.PushTint(ref highlightColor);
Render2D.DrawTriangles(_selectedTriangles, _selectedColors); Render2D.DrawTriangles(_selectedTriangles, _selectedColors);
Render2D.PopTint(); Render2D.PopTint();
} }

View File

@@ -213,7 +213,7 @@ namespace FlaxEditor.Surface.Archetypes
if (base.OnMouseDoubleClick(location, button)) if (base.OnMouseDoubleClick(location, button))
return true; return true;
if (_headerRect.Contains(location)) if (_headerRect.Contains(ref location))
{ {
StartRenaming(); StartRenaming();
return true; return true;
@@ -364,7 +364,7 @@ namespace FlaxEditor.Surface.Archetypes
if (ClipChildren) if (ClipChildren)
{ {
GetDesireClientArea(out var clientArea); GetDesireClientArea(out var clientArea);
Render2D.PushClip(clientArea); Render2D.PushClip(ref clientArea);
} }
DrawChildren(); DrawChildren();
@@ -382,13 +382,13 @@ namespace FlaxEditor.Surface.Archetypes
/// <inheritdoc /> /// <inheritdoc />
public override bool CanSelect(ref Float2 location) public override bool CanSelect(ref Float2 location)
{ {
return _dragAreaRect.MakeOffsetted(Location).Contains(location); return _dragAreaRect.MakeOffsetted(Location).Contains(ref location);
} }
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button) public override bool OnMouseDown(Float2 location, MouseButton button)
{ {
if (button == MouseButton.Left && !_dragAreaRect.Contains(location)) if (button == MouseButton.Left && !_dragAreaRect.Contains(ref location))
{ {
_isMouseDown = true; _isMouseDown = true;
Cursor = CursorType.Hand; Cursor = CursorType.Hand;
@@ -687,7 +687,7 @@ namespace FlaxEditor.Surface.Archetypes
var upperLeft = bounds.UpperLeft; var upperLeft = bounds.UpperLeft;
var bottomRight = bounds.BottomRight; var bottomRight = bounds.BottomRight;
bounds = Rectangle.FromPoints(PointToParent(ref upperLeft), PointToParent(ref bottomRight)); bounds = Rectangle.FromPoints(PointToParent(ref upperLeft), PointToParent(ref bottomRight));
CollisionsHelper.ClosestPointRectanglePoint(bounds, startPos, out endPos); CollisionsHelper.ClosestPointRectanglePoint(ref bounds, ref startPos, out endPos);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -731,15 +731,15 @@ namespace FlaxEditor.Surface.Archetypes
// Check click over the connection // Check click over the connection
var mousePosition = Surface.SurfaceRoot.PointFromParent(ref mouse); var mousePosition = Surface.SurfaceRoot.PointFromParent(ref mouse);
if (!TransitionsRectangle.Contains(mousePosition)) if (!TransitionsRectangle.Contains(ref mousePosition))
return; return;
for (int i = 0; i < Transitions.Count; i++) for (int i = 0; i < Transitions.Count; i++)
{ {
var t = Transitions[i]; var t = Transitions[i];
if (t.Bounds.Contains(mousePosition)) if (t.Bounds.Contains(ref mousePosition))
{ {
CollisionsHelper.ClosestPointPointLine(mousePosition, t.StartPos, t.EndPos, out var point); CollisionsHelper.ClosestPointPointLine(ref mousePosition, ref t.StartPos, ref t.EndPos, out var point);
if (Float2.DistanceSquared(mousePosition, point) < 25.0f) if (Float2.DistanceSquared(ref mousePosition, ref point) < 25.0f)
{ {
OnTransitionClicked(t, ref mouse, ref mousePosition, buttons); OnTransitionClicked(t, ref mouse, ref mousePosition, buttons);
handled = true; handled = true;
@@ -756,15 +756,15 @@ namespace FlaxEditor.Surface.Archetypes
// Check double click over the connection // Check double click over the connection
var mousePosition = Surface.SurfaceRoot.PointFromParent(ref mouse); var mousePosition = Surface.SurfaceRoot.PointFromParent(ref mouse);
if (!TransitionsRectangle.Contains(mousePosition)) if (!TransitionsRectangle.Contains(ref mousePosition))
return; return;
for (int i = 0; i < Transitions.Count; i++) for (int i = 0; i < Transitions.Count; i++)
{ {
var t = Transitions[i]; var t = Transitions[i];
if (t.Bounds.Contains(mousePosition)) if (t.Bounds.Contains(ref mousePosition))
{ {
CollisionsHelper.ClosestPointPointLine(mousePosition, t.StartPos, t.EndPos, out var point); CollisionsHelper.ClosestPointPointLine(ref mousePosition, ref t.StartPos, ref t.EndPos, out var point);
if (Float2.DistanceSquared(mousePosition, point) < 25.0f) if (Float2.DistanceSquared(ref mousePosition, ref point) < 25.0f)
{ {
t.EditRule(); t.EditRule();
handled = true; handled = true;
@@ -1007,7 +1007,7 @@ namespace FlaxEditor.Surface.Archetypes
var offset = diff ? -6.0f : 6.0f; var offset = diff ? -6.0f : 6.0f;
var dir = startPos - endPos; var dir = startPos - endPos;
dir.Normalize(); dir.Normalize();
Float2.Perpendicular(dir, out var nrm); Float2.Perpendicular(ref dir, out var nrm);
nrm *= offset; nrm *= offset;
startPos += nrm; startPos += nrm;
endPos += nrm; endPos += nrm;
@@ -1031,7 +1031,7 @@ namespace FlaxEditor.Surface.Archetypes
t.StartPos = startPos; t.StartPos = startPos;
t.EndPos = endPos; t.EndPos = endPos;
Rectangle.FromPoints(startPos, endPos, out t.Bounds); Rectangle.FromPoints(ref startPos, ref endPos, out t.Bounds);
t.Bounds.Expand(10.0f); t.Bounds.Expand(10.0f);
} }
@@ -1040,7 +1040,7 @@ namespace FlaxEditor.Surface.Archetypes
TransitionsRectangle = Transitions[0].Bounds; TransitionsRectangle = Transitions[0].Bounds;
for (int i = 1; i < Transitions.Count; i++) for (int i = 1; i < Transitions.Count; i++)
{ {
Rectangle.Union(TransitionsRectangle, Transitions[i].Bounds, out TransitionsRectangle); Rectangle.Union(ref TransitionsRectangle, ref Transitions[i].Bounds, out TransitionsRectangle);
} }
} }
else else
@@ -1095,7 +1095,7 @@ namespace FlaxEditor.Surface.Archetypes
if (ClipChildren) if (ClipChildren)
{ {
GetDesireClientArea(out var clientArea); GetDesireClientArea(out var clientArea);
Render2D.PushClip(clientArea); Render2D.PushClip(ref clientArea);
} }
DrawChildren(); DrawChildren();
@@ -1120,7 +1120,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <inheritdoc /> /// <inheritdoc />
public override bool CanSelect(ref Float2 location) public override bool CanSelect(ref Float2 location)
{ {
return _dragAreaRect.MakeOffsetted(Location).Contains(location); return _dragAreaRect.MakeOffsetted(Location).Contains(ref location);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -1129,7 +1129,7 @@ namespace FlaxEditor.Surface.Archetypes
if (base.OnMouseDoubleClick(location, button)) if (base.OnMouseDoubleClick(location, button))
return true; return true;
if (_renameButtonRect.Contains(location) || _closeButtonRect.Contains(location)) if (_renameButtonRect.Contains(ref location) || _closeButtonRect.Contains(ref location))
return true; return true;
return false; return false;
@@ -1138,7 +1138,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDown(Float2 location, MouseButton button) public override bool OnMouseDown(Float2 location, MouseButton button)
{ {
if (button == MouseButton.Left && !_dragAreaRect.Contains(location)) if (button == MouseButton.Left && !_dragAreaRect.Contains(ref location))
{ {
_isMouseDown = true; _isMouseDown = true;
Cursor = CursorType.Hand; Cursor = CursorType.Hand;
@@ -1271,11 +1271,11 @@ namespace FlaxEditor.Surface.Archetypes
for (int i = 0; i < Transitions.Count; i++) for (int i = 0; i < Transitions.Count; i++)
{ {
var t = Transitions[i]; var t = Transitions[i];
var isMouseOver = t.Bounds.Contains(mousePosition); var isMouseOver = t.Bounds.Contains(ref mousePosition);
if (isMouseOver) if (isMouseOver)
{ {
CollisionsHelper.ClosestPointPointLine(mousePosition, t.StartPos, t.EndPos, out var point); CollisionsHelper.ClosestPointPointLine(ref mousePosition, ref t.StartPos, ref t.EndPos, out var point);
isMouseOver = Float2.DistanceSquared(mousePosition, point) < 25.0f; isMouseOver = Float2.DistanceSquared(ref mousePosition, ref point) < 25.0f;
} }
var color = isMouseOver ? Color.Wheat : t.LineColor; var color = isMouseOver ? Color.Wheat : t.LineColor;
SurfaceStyle.DrawStraightConnection(t.StartPos, t.EndPos, color); SurfaceStyle.DrawStraightConnection(t.StartPos, t.EndPos, color);
@@ -1474,7 +1474,7 @@ namespace FlaxEditor.Surface.Archetypes
return true; return true;
// Rename // Rename
if (_renameButtonRect.Contains(location)) if (_renameButtonRect.Contains(ref location))
{ {
StartRenaming(); StartRenaming();
return true; return true;

View File

@@ -308,7 +308,7 @@ namespace FlaxEditor.Surface.Archetypes
if (base.OnMouseDoubleClick(location, button)) if (base.OnMouseDoubleClick(location, button))
return true; return true;
if (_nameField.Bounds.Contains(location) && Surface.CanEdit) if (_nameField.Bounds.Contains(ref location) && Surface.CanEdit)
{ {
StartRenaming(); StartRenaming();
return true; return true;
@@ -1128,7 +1128,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button) public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{ {
if (button == MouseButton.Left && _headerRect.Contains(location)) if (button == MouseButton.Left && _headerRect.Contains(ref location))
{ {
// Open function content item if exists // Open function content item if exists
var method = GetMethod(out var scriptType, out _, out _); var method = GetMethod(out var scriptType, out _, out _);
@@ -1759,7 +1759,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <inheritdoc /> /// <inheritdoc />
public override bool OnMouseDoubleClick(Float2 location, MouseButton button) public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
{ {
if (button == MouseButton.Left && _headerRect.Contains(location)) if (button == MouseButton.Left && _headerRect.Contains(ref location))
{ {
OnEditSignature(); OnEditSignature();
return true; return true;

View File

@@ -347,7 +347,7 @@ namespace FlaxEditor.Surface.Archetypes
public override bool CanSelect(ref Float2 location) public override bool CanSelect(ref Float2 location)
{ {
return base.CanSelect(ref location) && !_resizeButtonRect.MakeOffsetted(Location).Contains(location); return base.CanSelect(ref location) && !_resizeButtonRect.MakeOffsetted(Location).Contains(ref location);
} }
public override void OnSurfaceLoaded(SurfaceNodeActions action) public override void OnSurfaceLoaded(SurfaceNodeActions action)
@@ -414,7 +414,7 @@ namespace FlaxEditor.Surface.Archetypes
if (base.OnMouseDown(location, button)) if (base.OnMouseDown(location, button))
return true; return true;
if (button == MouseButton.Left && _resizeButtonRect.Contains(location) && Surface.CanEdit) if (button == MouseButton.Left && _resizeButtonRect.Contains(ref location) && Surface.CanEdit)
{ {
// Start sliding // Start sliding
_isResizing = true; _isResizing = true;

View File

@@ -182,7 +182,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <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();

View File

@@ -191,7 +191,7 @@ namespace FlaxEditor.Surface.Archetypes
// Header // Header
var headerColor = style.BackgroundHighlighted; var headerColor = style.BackgroundHighlighted;
if (_headerRect.Contains(_mousePosition)) if (_headerRect.Contains(ref _mousePosition))
headerColor *= 1.07f; headerColor *= 1.07f;
Render2D.FillRectangle(_headerRect, headerColor); Render2D.FillRectangle(_headerRect, headerColor);
Render2D.DrawText(style.FontLarge, Title, _headerRect, style.Foreground, TextAlignment.Center, TextAlignment.Center); Render2D.DrawText(style.FontLarge, Title, _headerRect, style.Foreground, TextAlignment.Center, TextAlignment.Center);

View File

@@ -113,7 +113,7 @@ namespace FlaxEditor.Surface.Archetypes
var icons = Editor.Instance.Icons; var icons = Editor.Instance.Icons;
var icon = isSelected ? icons.VisjectArrowClosed32 : icons.VisjectArrowOpen32; var icon = isSelected ? icons.VisjectArrowClosed32 : icons.VisjectArrowOpen32;
Render2D.PushTransform(arrowTransform); Render2D.PushTransform(ref arrowTransform);
Render2D.DrawSprite(icon, arrowRect, color); Render2D.DrawSprite(icon, arrowRect, color);
Render2D.PopTransform(); Render2D.PopTransform();
} }
@@ -169,7 +169,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <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;
int index = Node._stops.IndexOf(this); int index = Node._stops.IndexOf(this);
@@ -1076,12 +1076,12 @@ namespace FlaxEditor.Surface.Archetypes
} }
/// <inheritdoc /> /// <inheritdoc />
protected override bool ShowTooltip => !string.IsNullOrEmpty(TooltipText) && _localBounds.Contains(_mousePosition) && !Surface.IsLeftMouseButtonDown && !Surface.IsRightMouseButtonDown && !Surface.IsPrimaryMenuOpened; protected override bool ShowTooltip => !string.IsNullOrEmpty(TooltipText) && _localBounds.Contains(ref _mousePosition) && !Surface.IsLeftMouseButtonDown && !Surface.IsRightMouseButtonDown && !Surface.IsPrimaryMenuOpened;
/// <inheritdoc /> /// <inheritdoc />
public override bool OnTestTooltipOverControl(ref Float2 location) public override bool OnTestTooltipOverControl(ref Float2 location)
{ {
return _localBounds.Contains(location) && ShowTooltip; return _localBounds.Contains(ref location) && ShowTooltip;
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -1150,7 +1150,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <inheritdoc /> /// <inheritdoc />
public override bool CanSelect(ref Float2 location) public override bool CanSelect(ref Float2 location)
{ {
return new Rectangle(Location, DefaultSize).Contains(location); return new Rectangle(Location, DefaultSize).Contains(ref location);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -1230,7 +1230,7 @@ namespace FlaxEditor.Surface.Archetypes
/// <inheritdoc /> /// <inheritdoc />
public override void OnMouseMove(Float2 location) public override void OnMouseMove(Float2 location)
{ {
_isMouseInConnectingBounds = IsMouseOver && _localBounds.MakeExpanded(ConnectingBounds).Contains(location); // Inner area for connecting, outer area for moving _isMouseInConnectingBounds = IsMouseOver && _localBounds.MakeExpanded(ConnectingBounds).Contains(ref location); // Inner area for connecting, outer area for moving
if (!_isMouseInConnectingBounds && !_isMouseDown) if (!_isMouseInConnectingBounds && !_isMouseDown)
Cursor = CursorType.SizeAll; Cursor = CursorType.SizeAll;
else else

View File

@@ -156,7 +156,7 @@ namespace FlaxEditor.Surface.Elements
Bezier(ref offsetStart, ref control1, ref control2, ref offsetEnd, t, out p); Bezier(ref offsetStart, ref control1, ref control2, ref offsetEnd, t, out p);
// Maybe it would be reasonable to return the point? // Maybe it would be reasonable to return the point?
CollisionsHelper.ClosestPointPointLine(point, oldp, p, out var result); CollisionsHelper.ClosestPointPointLine(ref point, ref oldp, ref p, out var result);
if (Float2.DistanceSquared(point, result) <= squaredDistance) if (Float2.DistanceSquared(point, result) <= squaredDistance)
{ {
return true; return true;
@@ -167,12 +167,12 @@ namespace FlaxEditor.Surface.Elements
private static void Bezier(ref Float2 p0, ref Float2 p1, ref Float2 p2, ref Float2 p3, float alpha, out Float2 result) private static void Bezier(ref Float2 p0, ref Float2 p1, ref Float2 p2, ref Float2 p3, float alpha, out Float2 result)
{ {
Float2.Lerp(p0, p1, alpha, out var p01); Float2.Lerp(ref p0, ref p1, alpha, out var p01);
Float2.Lerp(p1, p2, alpha, out var p12); Float2.Lerp(ref p1, ref p2, alpha, out var p12);
Float2.Lerp(p2, p3, alpha, out var p23); Float2.Lerp(ref p2, ref p3, alpha, out var p23);
Float2.Lerp(p01, p12, alpha, out var p012); Float2.Lerp(ref p01, ref p12, alpha, out var p012);
Float2.Lerp(p12, p23, alpha, out var p123); Float2.Lerp(ref p12, ref p23, alpha, out var p123);
Float2.Lerp(p012, p123, alpha, out result); Float2.Lerp(ref p012, ref p123, alpha, out result);
} }
/// <summary> /// <summary>

View File

@@ -146,13 +146,13 @@ namespace FlaxEditor.Surface
/// <inheritdoc /> /// <inheritdoc />
public override bool CanSelect(ref Float2 location) public override bool CanSelect(ref Float2 location)
{ {
return _headerRect.MakeOffsetted(Location).Contains(location) && !_resizeButtonRect.MakeOffsetted(Location).Contains(location); return _headerRect.MakeOffsetted(Location).Contains(ref location) && !_resizeButtonRect.MakeOffsetted(Location).Contains(ref location);
} }
/// <inheritdoc /> /// <inheritdoc />
public override bool IsSelectionIntersecting(ref Rectangle selectionRect) public override bool IsSelectionIntersecting(ref Rectangle selectionRect)
{ {
return _headerRect.MakeOffsetted(Location).Intersects(selectionRect); return _headerRect.MakeOffsetted(Location).Intersects(ref selectionRect);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -287,7 +287,7 @@ namespace FlaxEditor.Surface
/// <inheritdoc /> /// <inheritdoc />
public override bool ContainsPoint(ref Float2 location, bool precise) public override bool ContainsPoint(ref Float2 location, bool precise)
{ {
return _headerRect.Contains(location) || _resizeButtonRect.Contains(location); return _headerRect.Contains(ref location) || _resizeButtonRect.Contains(ref location);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -297,7 +297,7 @@ namespace FlaxEditor.Surface
return true; return true;
// Check if can start resizing // Check if can start resizing
if (button == MouseButton.Left && _resizeButtonRect.Contains(location) && Surface.CanEdit) if (button == MouseButton.Left && _resizeButtonRect.Contains(ref location) && Surface.CanEdit)
{ {
// Start sliding // Start sliding
_isResizing = true; _isResizing = true;
@@ -336,7 +336,7 @@ namespace FlaxEditor.Surface
return true; return true;
// Rename // Rename
if (_headerRect.Contains(location) && Surface.CanEdit) if (_headerRect.Contains(ref location) && Surface.CanEdit)
{ {
StartRenaming(); StartRenaming();
return true; return true;
@@ -404,14 +404,14 @@ namespace FlaxEditor.Surface
return true; return true;
// Close // Close
if (_closeButtonRect.Contains(location) && Surface.CanEdit) if (_closeButtonRect.Contains(ref location) && Surface.CanEdit)
{ {
Surface.Delete(this); Surface.Delete(this);
return true; return true;
} }
// Color // Color
if (_colorButtonRect.Contains(location) && Surface.CanEdit) if (_colorButtonRect.Contains(ref location) && Surface.CanEdit)
{ {
ColorValueBox.ShowPickColorDialog?.Invoke(this, Color, OnColorChanged); ColorValueBox.ShowPickColorDialog?.Invoke(this, Color, OnColorChanged);
return true; return true;

View File

@@ -93,7 +93,7 @@ namespace FlaxEditor.Surface
/// <returns><c>true</c> if the selection rectangle is intersecting with the selectable parts of the control ; otherwise, <c>false</c>.</returns> /// <returns><c>true</c> if the selection rectangle is intersecting with the selectable parts of the control ; otherwise, <c>false</c>.</returns>
public virtual bool IsSelectionIntersecting(ref Rectangle selectionRect) public virtual bool IsSelectionIntersecting(ref Rectangle selectionRect)
{ {
return Bounds.Intersects(selectionRect); return Bounds.Intersects(ref selectionRect);
} }
/// <summary> /// <summary>

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