Compare commits
186 Commits
master_fix
...
3008d8037d
| Author | SHA1 | Date | |
|---|---|---|---|
| 3008d8037d | |||
| 0973363c64 | |||
| 5d45b9ea1c | |||
| c40f7c12f2 | |||
| 1b2d6372b2 | |||
| 0782ea889c | |||
| ef89501111 | |||
| 608353b996 | |||
| 221325ef09 | |||
| 8f57c91a9e | |||
| 968de34cae | |||
| 6586a98f8d | |||
| b3510b0e44 | |||
| d5a92c1942 | |||
| 417f82826f | |||
| 63bed0986a | |||
| c40eefc79d | |||
| d68631dd20 | |||
| e77b772010 | |||
| e41e956386 | |||
| 33e47c646b | |||
| b30ce6b84f | |||
| 02f67b25f3 | |||
| 469a422681 | |||
| 42fa0ffdd1 | |||
| f97ee72f1c | |||
| 89c93dd4f7 | |||
| 60cd8f702e | |||
| f376ec5c8a | |||
| 82bb297119 | |||
| ed994cb560 | |||
| 8efe2134f0 | |||
| 8efc4715c6 | |||
| 48c60144ae | |||
| 249cde467e | |||
| e2eadc87b6 | |||
| bc4b94d2bc | |||
| ecf074801f | |||
| 74bac97f44 | |||
| d7eebb699c | |||
| dde07bac8d | |||
| 5c8e593d89 | |||
| 46fd5a5855 | |||
| 74c1e200ce | |||
| 31945a53a2 | |||
| 3e91ba3fb2 | |||
| 092beb6ae9 | |||
| eb69186271 | |||
| 0ac3ab2329 | |||
| 466f9a4797 | |||
| c61ecc0545 | |||
| 22ba7f2ee5 | |||
| f52f3920cb | |||
| f99a244b8e | |||
| 668a4dbb4d | |||
| 1d8f221f1b | |||
| d70a003617 | |||
| b443b74d18 | |||
| fc341a86e7 | |||
| 68da28ffe8 | |||
|
|
427e76e76e | ||
| b183b5bcfc | |||
| 51feaa0730 | |||
| 8e69aa8bd6 | |||
| 90b2fded48 | |||
| 9125ffeb9e | |||
| 28980e5fbf | |||
| aab0d772a4 | |||
| 6296e1a9eb | |||
| 1586bb0702 | |||
| edeaf6af09 | |||
| 951edd95db | |||
| 9951211596 | |||
| 6d337464f7 | |||
| d0b552d74a | |||
| 83512822b1 | |||
| ccb78103ec | |||
| 6e79ffea34 | |||
| 4f03d37a17 | |||
| 6fb8419b3c | |||
| a4272d6ca9 | |||
| 4654117d5e | |||
| 6ff260d052 | |||
| 88d2b72822 | |||
| 29868531ad | |||
| 95dfb6fdc6 | |||
| 8df3999f85 | |||
| 149b189629 | |||
| b1fd86e6b5 | |||
| 5e8fdf879d | |||
| 84ada18299 | |||
| 635fe8017e | |||
| 834380ff05 | |||
| dd65fc2289 | |||
| 86125bb625 | |||
| 09a9d8b380 | |||
| 86b223ec93 | |||
| 78f6080321 | |||
| c7be6f6e0e | |||
| c40c31fbb7 | |||
| f5fbc1e32d | |||
| 0a20378acd | |||
| d4e87877b6 | |||
| 7eb7236b8a | |||
| dc0e4ffce2 | |||
| 86fe93943d | |||
| 3258113ef8 | |||
| ebf3999cfe | |||
| a1ccbbb5b9 | |||
| 35072c40d8 | |||
| 5c51021388 | |||
| 95fd527515 | |||
| 113d851cea | |||
| 72f0c460f9 | |||
| 13ddd15b44 | |||
| c9e24aaf5f | |||
| 68c0ac0ffc | |||
| bebda275a9 | |||
| 287eaae850 | |||
| 7e59c3b9a7 | |||
| 38658a5b8c | |||
| 88c75b8672 | |||
| 17ab1e6830 | |||
| 1f45110e5f | |||
| 5401166a07 | |||
| bfa8188782 | |||
| e777a71784 | |||
| c13e91a0d0 | |||
| aac5d57352 | |||
| ceca13c7b6 | |||
| 2905470330 | |||
| 2c17033822 | |||
| 0a4cb9e9b1 | |||
| 096651f4c1 | |||
| 275a08506b | |||
| 4cd61cb381 | |||
| 9ad1147581 | |||
| 35e09def1b | |||
| 0469607a71 | |||
| d115d22ee6 | |||
| 8120ae621d | |||
| f873c2fa9f | |||
| c3ffbe2f42 | |||
| 55a0a39881 | |||
| 592215dd30 | |||
| ef0c2a2785 | |||
| 37979e452a | |||
| e9671bb727 | |||
| aa328bd591 | |||
| 188e4313f9 | |||
| df02c70e31 | |||
| 257f54b323 | |||
| fb4b5b2575 | |||
| 4e1251276d | |||
| a7b200dc57 | |||
| 8cadbae80e | |||
| c3bae49aae | |||
|
|
6fa4fc6149 | ||
| f1ffe1acaa | |||
| 5c9ddf7f00 | |||
| 431767a150 | |||
| 8ba4e442a6 | |||
| 2f8d19c267 | |||
| f2fd98f742 | |||
| 3ce35d6e81 | |||
| 796dbaa836 | |||
| 84b209ec7f | |||
| fa976b34dc | |||
| e7cda362b7 | |||
| a41a09c162 | |||
| e82f84f0ab | |||
| f1d387ceea | |||
| 3893d4d1f8 | |||
| cf7ac50faf | |||
| 3f6bf15554 | |||
| dac74829b4 | |||
| 94d6f213a0 | |||
| 8f2550ef61 | |||
| b622a1cc5e | |||
| c83a3c32c7 | |||
| e7dcf7f7e7 | |||
| 398785a2be | |||
| 05dba0f1f5 | |||
| 39dbd32b2e | |||
| 23a34a455a | |||
| 4308328b48 |
4
.github/workflows/build_linux.yml
vendored
4
.github/workflows/build_linux.yml
vendored
@@ -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
|
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
|
||||||
- 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
|
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev libwayland-dev
|
||||||
- name: Setup Vulkan
|
- name: Setup Vulkan
|
||||||
uses: ./.github/actions/vulkan
|
uses: ./.github/actions/vulkan
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
|
|||||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -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
|
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
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
|
./GenerateProjectFiles.sh -vs2022 -log -verbose -printSDKs -dotnet=8
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"Configuration": {
|
"Configuration": {
|
||||||
"UseCSharp": true,
|
"UseCSharp": true,
|
||||||
"UseLargeWorlds": false,
|
"UseLargeWorlds": false,
|
||||||
"UseDotNet": true
|
"UseDotNet": true,
|
||||||
|
"UseSDL": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ if errorlevel 1 goto BuildToolFailed
|
|||||||
|
|
||||||
:: Build bindings for all editor configurations
|
:: Build bindings for all editor configurations
|
||||||
echo Building C# bindings...
|
echo Building C# bindings...
|
||||||
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor
|
Binaries\Tools\Flax.Build.exe -build -BuildBindingsOnly -arch=x64 -platform=Windows --buildTargets=FlaxEditor,FlaxGame
|
||||||
|
|
||||||
popd
|
popd
|
||||||
echo Done!
|
echo Done!
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ namespace FlaxEditor.Content
|
|||||||
|
|
||||||
if (data is DragDataFiles)
|
if (data is DragDataFiles)
|
||||||
return DragDropEffect.Copy;
|
return DragDropEffect.Copy;
|
||||||
return _dragOverItems.Effect;
|
return _dragOverItems?.Effect ?? DragDropEffect.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -749,7 +749,7 @@ namespace FlaxEditor.Content
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw short name
|
// Draw short name
|
||||||
Render2D.PushClip(ref textRect);
|
Render2D.PushClip(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();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace FlaxEditor.Content
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string TypeDescription => Path.EndsWith(".h") ? "C++ Header File" : "C++ Source Code";
|
public override string TypeDescription => Path.EndsWith(".h") || Path.EndsWith(".hpp") ? "C++ Header File" : "C++ Source Code";
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CPPScript128;
|
public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.CPPScript128;
|
||||||
|
|||||||
@@ -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(ref desc);
|
_output.Init(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;
|
||||||
|
|||||||
@@ -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(ref prefabObjectId);
|
var prefabInstance = prefab.GetDefaultInstance(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(ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
|
prefab.GetNestedObject(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(ref prefabObjectId);
|
var prefabInstance = prefab.GetDefaultInstance(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), ref prefabId, ref prefabObjectId);
|
Script.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), prefabId, 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), ref prefabId, ref prefabObjectId);
|
Actor.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), prefabId, prefabObjectId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.cpp", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.c", SearchOption.AllDirectories)).ToArray();
|
||||||
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);
|
files = Directory.GetFiles(Globals.ProjectSourceFolder, "*.h", SearchOption.AllDirectories).Concat(Directory.GetFiles(Globals.ProjectSourceFolder, "*.hpp", SearchOption.AllDirectories)).ToArray();;
|
||||||
filesCount += files.Length;
|
filesCount += files.Length;
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
FindNewKeysCpp(file, newKeys, allKeys);
|
FindNewKeysCpp(file, newKeys, allKeys);
|
||||||
|
|||||||
@@ -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(ref location))
|
if (isSelected && button1Rect.Contains(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(ref location))
|
if ((isSelected ? button2Rect : button1Rect).Contains(location))
|
||||||
ShowDropDownMenu();
|
ShowDropDownMenu();
|
||||||
|
|
||||||
return base.OnMouseUp(location, button);
|
return base.OnMouseUp(location, button);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public class ModelPrefabEditor : GenericEditor
|
|||||||
if (prefab)
|
if (prefab)
|
||||||
{
|
{
|
||||||
var prefabObjectId = modelPrefab.PrefabObjectID;
|
var prefabObjectId = modelPrefab.PrefabObjectID;
|
||||||
var prefabObject = prefab.GetDefaultInstance(ref prefabObjectId);
|
var prefabObject = prefab.GetDefaultInstance(prefabObjectId);
|
||||||
if (prefabObject.PrefabID == _prefabId)
|
if (prefabObject.PrefabID == _prefabId)
|
||||||
break;
|
break;
|
||||||
_prefabId = prefabObject.PrefabID;
|
_prefabId = prefabObject.PrefabID;
|
||||||
|
|||||||
@@ -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(ref location))
|
if (DropdownRect.Contains(location))
|
||||||
{
|
{
|
||||||
Focus();
|
Focus();
|
||||||
ShowPicker();
|
ShowPicker();
|
||||||
@@ -206,7 +206,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
{
|
{
|
||||||
base.OnMouseMove(location);
|
base.OnMouseMove(location);
|
||||||
|
|
||||||
if (DropdownRect.Contains(ref location))
|
if (DropdownRect.Contains(location))
|
||||||
Cursor = CursorType.Default;
|
Cursor = CursorType.Default;
|
||||||
else
|
else
|
||||||
Cursor = CursorType.IBeam;
|
Cursor = CursorType.IBeam;
|
||||||
|
|||||||
@@ -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(ref location))
|
if (button == MouseButton.Left && _arrangeButtonRect.Contains(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(ref location))
|
if (button == MouseButton.Left && _arrangeButtonRect.Contains(location))
|
||||||
{
|
{
|
||||||
_arrangeButtonInUse = true;
|
_arrangeButtonInUse = true;
|
||||||
Focus();
|
Focus();
|
||||||
|
|||||||
@@ -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(ref location))
|
if (_value != null && button1Rect.Contains(location))
|
||||||
Value = null;
|
Value = null;
|
||||||
|
|
||||||
// Picker dropdown menu
|
// Picker dropdown menu
|
||||||
if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(ref location))
|
if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(location))
|
||||||
{
|
{
|
||||||
ShowDropDownMenu();
|
ShowDropDownMenu();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -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);
|
return GetItemsForType(type, type.IsClass, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -273,10 +273,14 @@ 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 or setter
|
// Skip properties without getter
|
||||||
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;
|
||||||
|
|||||||
@@ -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(ref location) && _type == ScriptType.Null)
|
if (_value && button1Rect.Contains(location) && _type == ScriptType.Null)
|
||||||
Value = ScriptType.Null;
|
Value = ScriptType.Null;
|
||||||
|
|
||||||
// Picker dropdown menu
|
// Picker dropdown menu
|
||||||
if ((isSelected && _type == ScriptType.Null ? button2Rect : button1Rect).Contains(ref location))
|
if ((isSelected && _type == ScriptType.Null ? button2Rect : button1Rect).Contains(location))
|
||||||
ShowDropDownMenu();
|
ShowDropDownMenu();
|
||||||
|
|
||||||
return base.OnMouseUp(location, button);
|
return base.OnMouseUp(location, button);
|
||||||
|
|||||||
@@ -526,6 +526,23 @@ 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())
|
||||||
{
|
{
|
||||||
@@ -541,7 +558,7 @@ int32 Editor::LoadProduct()
|
|||||||
Array<String> files;
|
Array<String> files;
|
||||||
if (FileSystem::ShowOpenFileDialog(
|
if (FileSystem::ShowOpenFileDialog(
|
||||||
nullptr,
|
nullptr,
|
||||||
StringView::Empty,
|
lastProjectPath,
|
||||||
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"),
|
||||||
@@ -625,6 +642,10 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(ref box, out sphere);
|
BoundingSphere.FromBox(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);
|
||||||
|
|||||||
@@ -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(ref _mouseDownPos))
|
if (new Rectangle(Float2.Zero, Size).Contains(_mouseDownPos))
|
||||||
{
|
{
|
||||||
if (Validator.SelectedAsset != null)
|
if (Validator.SelectedAsset != null)
|
||||||
DoDragDrop(DragAssets.GetDragData(Validator.SelectedAsset));
|
DoDragDrop(DragAssets.GetDragData(Validator.SelectedAsset));
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_WINDOWS || PLATFORM_SDL
|
||||||
#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;
|
||||||
@@ -122,7 +125,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Shows the empty menu popup o na screen.
|
/// Shows the empty menu popup on a 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>
|
||||||
@@ -257,7 +260,9 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
desc.AllowMaximize = false;
|
desc.AllowMaximize = false;
|
||||||
desc.AllowDragAndDrop = false;
|
desc.AllowDragAndDrop = false;
|
||||||
desc.IsTopmost = true;
|
desc.IsTopmost = true;
|
||||||
desc.IsRegularWindow = false;
|
desc.Type = WindowType.Popup;
|
||||||
|
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);
|
||||||
@@ -266,6 +271,12 @@ 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;
|
||||||
@@ -441,6 +452,17 @@ 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;
|
||||||
@@ -454,6 +476,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private void OnWindowLostFocus()
|
private void OnWindowLostFocus()
|
||||||
{
|
{
|
||||||
@@ -552,7 +575,12 @@ 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
|
||||||
|
|||||||
@@ -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(ref selectionRect);
|
p.IsSelected = p.Bounds.Intersects(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(ref _movingSelectionStartPosLock, ref location) < 1.5f)
|
if (Float2.Distance(_movingSelectionStartPosLock, location) < 1.5f)
|
||||||
return;
|
return;
|
||||||
_movingSelectionStartPosLock = Float2.Minimum;
|
_movingSelectionStartPosLock = Float2.Minimum;
|
||||||
|
|
||||||
|
|||||||
@@ -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(ref posMin, ref pos, out posMin);
|
Float2.Min(posMin, pos, out posMin);
|
||||||
Float2.Max(ref posMax, ref pos, out posMax);
|
Float2.Max(posMax, 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(ref posMin, ref posMax, out posMin);
|
Float2.Min(posMin, posMax, out posMin);
|
||||||
Float2.Max(ref posMax, ref tmp, out posMax);
|
Float2.Max(posMax, 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(ref posMin, ref posMax, out posMin);
|
Float2.Min(posMin, posMax, out posMin);
|
||||||
Float2.Max(ref posMax, ref tmp, out posMax);
|
Float2.Max(posMax, 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(ref viewRect);
|
Render2D.PushClip(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(ref rect);
|
Render2D.PushClip(rect);
|
||||||
DrawCurve(ref viewRect);
|
DrawCurve(ref viewRect);
|
||||||
Render2D.PopClip();
|
Render2D.PopClip();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,8 +326,11 @@ 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;
|
||||||
SelectedColor = ScreenUtilities.GetColorAt(mousePosition);
|
Color color = ScreenUtilities.GetColorAt(mousePosition);
|
||||||
|
if (color != Color.Transparent)
|
||||||
|
SelectedColor = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,545 +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 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -19,11 +19,7 @@ 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;
|
||||||
#if PLATFORM_WINDOWS
|
private readonly bool _hideTabForSingleTab = Utilities.Utils.HideSingleTabWindowTabBars();
|
||||||
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).
|
||||||
@@ -54,6 +50,11 @@ 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.
|
||||||
@@ -196,7 +197,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
|
||||||
DockHintWindow.Create(_panel as FloatWindowDockPanel);
|
WindowDragHelper.StartDragging(_panel as FloatWindowDockPanel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -207,7 +208,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
_panel.SelectTab(index - 1);
|
_panel.SelectTab(index - 1);
|
||||||
|
|
||||||
// Create docking hint window
|
// Create docking hint window
|
||||||
DockHintWindow.Create(win);
|
WindowDragHelper.StartDragging(win, _panel.RootWindow.Window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -393,6 +394,7 @@ 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)
|
||||||
@@ -479,6 +481,20 @@ 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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -182,6 +182,25 @@ 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();
|
||||||
|
|
||||||
@@ -199,14 +218,17 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
windowGUI.UnlockChildrenRecursive();
|
windowGUI.UnlockChildrenRecursive();
|
||||||
windowGUI.PerformLayout();
|
windowGUI.PerformLayout();
|
||||||
|
|
||||||
// Show
|
if (showWindow)
|
||||||
window.Show();
|
{
|
||||||
window.BringToFront();
|
// Show
|
||||||
window.Focus();
|
window.Show();
|
||||||
OnShow();
|
window.BringToFront();
|
||||||
|
window.Focus();
|
||||||
|
OnShow();
|
||||||
|
|
||||||
// Perform layout again
|
// Perform layout again
|
||||||
windowGUI.PerformLayout();
|
windowGUI.PerformLayout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -11,6 +11,42 @@ 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;
|
||||||
|
|
||||||
@@ -40,6 +76,26 @@ 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>
|
||||||
@@ -52,7 +108,7 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Create docking hint window
|
// Create docking hint window
|
||||||
DockHintWindow.Create(this);
|
WindowDragHelper.StartDragging(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -71,22 +127,28 @@ 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(1);
|
settings.MinimumSize = new Float2(200, 150);
|
||||||
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 = false;
|
settings.SupportsTransparency = true;
|
||||||
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.IsRegularWindow = true;
|
settings.Type = WindowType.Regular;
|
||||||
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);
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ 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];
|
||||||
@@ -94,9 +93,44 @@ 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
|
||||||
|
|||||||
458
Source/Editor/GUI/Docking/WindowDragHelper.cs
Normal file
458
Source/Editor/GUI/Docking/WindowDragHelper.cs
Normal file
@@ -0,0 +1,458 @@
|
|||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -180,7 +180,7 @@ namespace FlaxEditor.GUI.Input
|
|||||||
Focus();
|
Focus();
|
||||||
float mousePosition = location.X;
|
float mousePosition = location.X;
|
||||||
|
|
||||||
if (_thumbRect.Contains(ref location))
|
if (_thumbRect.Contains(location))
|
||||||
{
|
{
|
||||||
// Start sliding
|
// Start sliding
|
||||||
_isSliding = true;
|
_isSliding = true;
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -292,13 +293,45 @@ 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,16 +12,6 @@ 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>
|
||||||
@@ -60,200 +50,12 @@ 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>
|
||||||
/// <param name="mainWindow">The main window.</param>
|
public MainMenu()
|
||||||
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>
|
||||||
@@ -298,26 +100,6 @@ 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)
|
||||||
{
|
{
|
||||||
@@ -333,16 +115,8 @@ namespace FlaxEditor.GUI
|
|||||||
protected override void PerformLayoutAfterChildren()
|
protected override void PerformLayoutAfterChildren()
|
||||||
{
|
{
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
WindowDecorations decorations = Parent.GetChild<WindowDecorations>();
|
||||||
#if PLATFORM_WINDOWS
|
x += decorations?.Icon?.Width ?? 0;
|
||||||
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;
|
||||||
@@ -361,37 +135,21 @@ namespace FlaxEditor.GUI
|
|||||||
x += b.Width;
|
x += b.Width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
// Fill the right side if title and buttons are not present
|
||||||
if (_useCustomWindowSystem)
|
if (decorations?.Title == null)
|
||||||
{
|
Width = Parent.Width;
|
||||||
// Buttons
|
else
|
||||||
_closeButton.Height = Height;
|
Width = x;
|
||||||
_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 (_window != null)
|
if (_selected != null)
|
||||||
{
|
Selected = null;
|
||||||
_window.Closed -= OnWindowClosed;
|
|
||||||
OnWindowClosed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,14 +42,12 @@ namespace FlaxEditor.GUI
|
|||||||
Text = text;
|
Text = text;
|
||||||
|
|
||||||
var style = Style.Current;
|
var style = Style.Current;
|
||||||
#if PLATFORM_WINDOWS
|
if (!Utilities.Utils.UseCustomWindowDecorations())
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(ref selectRay))
|
if (sphere.Intersects(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(ref selectRay))
|
if (box.Intersects(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(ref selectRay))
|
if (box.Intersects(selectRay))
|
||||||
{
|
{
|
||||||
SelectKeyframe(_track, i, 2);
|
SelectKeyframe(_track, i, 2);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -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(ref location, ref _startMovePos) > 25.0f)
|
if (_isMoving && Float2.DistanceSquared(location, _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(ref clientArea);
|
Render2D.PushClip(clientArea);
|
||||||
|
|
||||||
var style = Style.Current;
|
var style = Style.Current;
|
||||||
var bounds = new Rectangle(Float2.Zero, Size);
|
var bounds = new Rectangle(Float2.Zero, Size);
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ namespace FlaxEditor.GUI
|
|||||||
{
|
{
|
||||||
if (Children[i] is KeyframePoint p)
|
if (Children[i] is KeyframePoint p)
|
||||||
{
|
{
|
||||||
p.IsSelected = p.Bounds.Intersects(ref selectionRect);
|
p.IsSelected = p.Bounds.Intersects(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(ref location, ref _rightMouseDownPos) < 2.0f)
|
if (Float2.Distance(location, _rightMouseDownPos) < 2.0f)
|
||||||
{
|
{
|
||||||
var selectionCount = _editor.SelectionCount;
|
var selectionCount = _editor.SelectionCount;
|
||||||
var point = GetChildAt(location) as KeyframePoint;
|
var point = GetChildAt(location) as KeyframePoint;
|
||||||
|
|||||||
@@ -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(ref m1, ref m2, out var m3);
|
Matrix3x3.Multiply(m1, m2, out var m3);
|
||||||
Render2D.PushTransform(ref m3);
|
Render2D.PushTransform(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(ref textMatrix);
|
Render2D.PushTransform(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();
|
||||||
|
|
||||||
|
|||||||
@@ -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(ref _mouseLocation))
|
else if (IsMouseOver && CanResize && MoveLeftEdgeRect.Contains(_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(ref _mouseLocation))
|
else if (IsMouseOver && CanResize && MoveRightEdgeRect.Contains(_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(ref location) && CanResize;
|
_startMoveLeftEdge = MoveLeftEdgeRect.Contains(location) && CanResize;
|
||||||
_startMoveRightEdge = MoveRightEdgeRect.Contains(ref location) && CanResize;
|
_startMoveRightEdge = MoveRightEdgeRect.Contains(location) && CanResize;
|
||||||
StartMouseCapture(true);
|
StartMouseCapture(true);
|
||||||
if (_startMoveLeftEdge || _startMoveRightEdge)
|
if (_startMoveLeftEdge || _startMoveRightEdge)
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -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(ref selectRay))
|
if (select && sphere.Intersects(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(ref selectRay))
|
if (select && box.Intersects(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(ref selectRay))
|
if (select && box.Intersects(selectRay))
|
||||||
SelectKeyframeGizmo(curveTrack, i, 2);
|
SelectKeyframeGizmo(curveTrack, i, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(ref location, ref _rightMouseButtonDownPos) < 4.0f)
|
if (Float2.Distance(location, _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(ref mediaRect))
|
if (media.Bounds.Intersects(mediaRect))
|
||||||
{
|
{
|
||||||
SelectedMedia.Add(media);
|
SelectedMedia.Add(media);
|
||||||
selectionChanged = true;
|
selectionChanged = true;
|
||||||
|
|||||||
@@ -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(ref location);
|
return new Rectangle(0, 0, Width, HeaderHeight).Contains(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -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(ref location);
|
return rect.Contains(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.ContainsPoint(ref location, precise);
|
return base.ContainsPoint(ref location, precise);
|
||||||
|
|||||||
@@ -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(ref desc);
|
_output.Init(desc);
|
||||||
}
|
}
|
||||||
if (_task == null)
|
if (_task == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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(ref nodeArea))
|
if (child.IsExpanded && range.Intersects(nodeArea))
|
||||||
WalkSelectRangeExpandedTree(selection, child, ref range);
|
WalkSelectRangeExpandedTree(selection, child, ref range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(ref location);
|
return _headerRect.Contains(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(ref child._cachedTransform);
|
Render2D.PushTransform(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(ref control._cachedTransform, ref globalTransform, out var globalChildTransform);
|
Matrix3x3.Multiply(control._cachedTransform, 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(ref child._cachedTransform);
|
Render2D.PushTransform(child._cachedTransform);
|
||||||
child.Draw();
|
child.Draw();
|
||||||
Render2D.PopTransform();
|
Render2D.PopTransform();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace FlaxEditor.GUI.Tree
|
|||||||
|
|
||||||
foreach (var child in Addons)
|
foreach (var child in Addons)
|
||||||
{
|
{
|
||||||
Render2D.PushTransform(ref child._cachedTransform);
|
Render2D.PushTransform(child._cachedTransform);
|
||||||
child.Draw();
|
child.Draw();
|
||||||
Render2D.PopTransform();
|
Render2D.PopTransform();
|
||||||
}
|
}
|
||||||
|
|||||||
342
Source/Editor/GUI/WindowDecorations.cs
Normal file
342
Source/Editor/GUI/WindowDecorations.cs
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
// 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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(ref desc);
|
var target = RenderTargetPool.Get(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(ref desc);
|
var targetDepth = RenderTargetPool.Get(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(ref renderContext, false, DrawCallsListType.GBuffer);
|
renderList.SortDrawCalls(renderContext, false, DrawCallsListType.GBuffer);
|
||||||
renderList.SortDrawCalls(ref renderContext, false, DrawCallsListType.GBufferNoDecals);
|
renderList.SortDrawCalls(renderContext, false, DrawCallsListType.GBufferNoDecals);
|
||||||
renderList.SortDrawCalls(ref renderContext, true, DrawCallsListType.Forward);
|
renderList.SortDrawCalls(renderContext, true, DrawCallsListType.Forward);
|
||||||
|
|
||||||
// Perform the rendering
|
// Perform the rendering
|
||||||
renderContext.View.Pass = DrawPass.GBuffer;
|
renderContext.View.Pass = DrawPass.GBuffer;
|
||||||
renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.GBuffer);
|
renderList.ExecuteDrawCalls(renderContext, DrawCallsListType.GBuffer);
|
||||||
renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.GBufferNoDecals);
|
renderList.ExecuteDrawCalls(renderContext, DrawCallsListType.GBufferNoDecals);
|
||||||
renderContext.View.Pass = DrawPass.Forward;
|
renderContext.View.Pass = DrawPass.Forward;
|
||||||
renderList.ExecuteDrawCalls(ref renderContext, DrawCallsListType.Forward);
|
renderList.ExecuteDrawCalls(renderContext, DrawCallsListType.Forward);
|
||||||
|
|
||||||
// Resolve MSAA texture
|
// Resolve MSAA texture
|
||||||
if (enableMsaa)
|
if (enableMsaa)
|
||||||
|
|||||||
@@ -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(ref desc);
|
_vertexBuffer.Init(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(ref desc);
|
_indexBuffer.Init(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(ref desc);
|
_psGrid.Init(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(ref renderContext.View.View, ref renderContext.View.Projection, out var viewProjection);
|
Matrix.Multiply(renderContext.View.View, renderContext.View.Projection, out var viewProjection);
|
||||||
Matrix.Transpose(ref viewProjection, out data.ViewProjectionMatrix);
|
Matrix.Transpose(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;
|
||||||
|
|||||||
@@ -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(ref desc);
|
var customDepth = RenderTargetPool.Get(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, ref renderContext, _material, output, input.View());
|
Renderer.DrawPostFxMaterial(context, renderContext, _material, output, input.View());
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
RenderTargetPool.Release(customDepth);
|
RenderTargetPool.Release(customDepth);
|
||||||
|
|||||||
@@ -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(ref editorBounds, ref b, out editorBounds);
|
BoundingBox.Merge(editorBounds, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(ref m3, ref world, out m1);
|
Matrix.Multiply(m3, 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(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance xAxisMaterialTransform = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
MaterialInstance xAxisMaterialTransform = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
transAxisMesh.Draw(ref renderContext, xAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
transAxisMesh.Draw(renderContext, xAxisMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance yAxisMaterialTransform = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
MaterialInstance yAxisMaterialTransform = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
transAxisMesh.Draw(ref renderContext, yAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
transAxisMesh.Draw(renderContext, yAxisMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(Mathf.Pi, out m2);
|
Matrix.RotationX(Mathf.Pi, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance zAxisMaterialTransform = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
MaterialInstance zAxisMaterialTransform = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
transAxisMesh.Draw(ref renderContext, zAxisMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
transAxisMesh.Draw(renderContext, zAxisMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// XY plane
|
// XY plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance xyPlaneMaterialTransform = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
MaterialInstance xyPlaneMaterialTransform = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(renderContext, xyPlaneMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// ZX plane
|
// ZX plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance zxPlaneMaterialTransform = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
MaterialInstance zxPlaneMaterialTransform = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(renderContext, zxPlaneMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// YZ plane
|
// YZ plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance yzPlaneMaterialTransform = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
MaterialInstance yzPlaneMaterialTransform = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialTransform, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(renderContext, yzPlaneMaterialTransform, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center sphere
|
// Center sphere
|
||||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
sphereMesh.Draw(renderContext, isCenter ? _materialAxisFocus : _materialSphere, 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(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
rotationAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
rotationAxisMesh.Draw(renderContext, xAxisMaterialRotate, 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(ref renderContext, yAxisMaterialRotate, ref m1, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
rotationAxisMesh.Draw(renderContext, yAxisMaterialRotate, m1, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(-Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(-Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
rotationAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
rotationAxisMesh.Draw(renderContext, zAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center box
|
// Center box
|
||||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
sphereMesh.Draw(renderContext, isCenter ? _materialAxisFocus : _materialSphere, 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(ref m2, ref mx1, out m3);
|
Matrix.Multiply(m2, mx1, out m3);
|
||||||
MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
MaterialInstance xAxisMaterialRotate = (isXAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
scaleAxisMesh.Draw(ref renderContext, xAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
scaleAxisMesh.Draw(renderContext, xAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Y axis
|
// Y axis
|
||||||
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
Matrix.RotationX(Mathf.PiOverTwo, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance yAxisMaterialRotate = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
MaterialInstance yAxisMaterialRotate = (isYAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
scaleAxisMesh.Draw(ref renderContext, yAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
scaleAxisMesh.Draw(renderContext, yAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Z axis
|
// Z axis
|
||||||
Matrix.RotationX(Mathf.Pi, out m2);
|
Matrix.RotationX(Mathf.Pi, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
MaterialInstance zAxisMaterialRotate = (isZAxis && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
scaleAxisMesh.Draw(ref renderContext, zAxisMaterialRotate, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
scaleAxisMesh.Draw(renderContext, zAxisMaterialRotate, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// XY plane
|
// XY plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance xyPlaneMaterialScale = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
MaterialInstance xyPlaneMaterialScale = (_activeAxis == Axis.XY && !_isDisabled) ? _materialAxisFocus : _materialAxisX;
|
||||||
cubeMesh.Draw(ref renderContext, xyPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(renderContext, xyPlaneMaterialScale, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// ZX plane
|
// ZX plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance zxPlaneMaterialScale = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
MaterialInstance zxPlaneMaterialScale = (_activeAxis == Axis.ZX && !_isDisabled) ? _materialAxisFocus : _materialAxisZ;
|
||||||
cubeMesh.Draw(ref renderContext, zxPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(renderContext, zxPlaneMaterialScale, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// YZ plane
|
// YZ plane
|
||||||
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
MaterialInstance yzPlaneMaterialScale = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
MaterialInstance yzPlaneMaterialScale = (_activeAxis == Axis.YZ && !_isDisabled) ? _materialAxisFocus : _materialAxisY;
|
||||||
cubeMesh.Draw(ref renderContext, yzPlaneMaterialScale, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(renderContext, yzPlaneMaterialScale, m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
|
|
||||||
// Center box
|
// Center box
|
||||||
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
|
||||||
Matrix.Multiply(ref m2, ref m1, out m3);
|
Matrix.Multiply(m2, m1, out m3);
|
||||||
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
sphereMesh.Draw(renderContext, isCenter ? _materialAxisFocus : _materialSphere, 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(ref renderContext, _materialSphere, ref matrix, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
cubeMesh.Draw(renderContext, _materialSphere, matrix, StaticFlags.None, true, DrawPass.Default, 0.0f, sortOrder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(ref ray, out distance))
|
if (!plane.Intersects(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(ref ray.Direction, out localRay.Direction);
|
_gizmoWorld.WorldToLocalVector(ray.Direction, out localRay.Direction);
|
||||||
_gizmoWorld.WorldToLocal(ref ray.Position, out localRay.Position);
|
_gizmoWorld.WorldToLocal(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(ref localRay, out intersection) && intersection < closestIntersection)
|
if (XAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.X;
|
_activeAxis = Axis.X;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (YAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
|
if (YAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.Y;
|
_activeAxis = Axis.Y;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ZAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
|
if (ZAxisBox.Intersects(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(ref localRay, out intersection) && intersection > closestIntersection)
|
if (XYBox.Intersects(localRay, out intersection) && intersection > closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.XY;
|
_activeAxis = Axis.XY;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (XZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
if (XZBox.Intersects(localRay, out intersection) && intersection > closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.ZX;
|
_activeAxis = Axis.ZX;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
if (YZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
if (YZBox.Intersects(localRay, out intersection) && intersection > closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.YZ;
|
_activeAxis = Axis.YZ;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// Center
|
/*// Center
|
||||||
if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
if (CenterBoxRaw.Intersects(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(ref localRay, out intersection) && intersection < closestIntersection)
|
if (XAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.X;
|
_activeAxis = Axis.X;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
if (YAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
|
if (YAxisBox.Intersects(localRay, out intersection) && intersection < closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.Y;
|
_activeAxis = Axis.Y;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
if (ZAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
|
if (ZAxisBox.Intersects(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(ref localRay, out intersection) && intersection > closestIntersection)
|
if (XYBox.Intersects(localRay, out intersection) && intersection > closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.XY;
|
_activeAxis = Axis.XY;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
if (XZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
if (XZBox.Intersects(localRay, out intersection) && intersection > closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.ZX;
|
_activeAxis = Axis.ZX;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
if (YZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
if (YZBox.Intersects(localRay, out intersection) && intersection > closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.YZ;
|
_activeAxis = Axis.YZ;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center
|
// Center
|
||||||
if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
|
if (CenterBoxRaw.Intersects(localRay, out intersection) && intersection > closestIntersection)
|
||||||
{
|
{
|
||||||
_activeAxis = Axis.Center;
|
_activeAxis = Axis.Center;
|
||||||
closestIntersection = intersection;
|
closestIntersection = intersection;
|
||||||
|
|||||||
@@ -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(ref _gizmoWorld.Orientation, out var rotationMatrix);
|
Matrix.RotationQuaternion(_gizmoWorld.Orientation, out var rotationMatrix);
|
||||||
Matrix.Invert(ref rotationMatrix, out var invRotationMatrix);
|
Matrix.Invert(rotationMatrix, out var invRotationMatrix);
|
||||||
ray.Position = Vector3.Transform(ray.Position, invRotationMatrix);
|
ray.Position = Vector3.Transform(ray.Position, invRotationMatrix);
|
||||||
Vector3.TransformNormal(ref ray.Direction, ref invRotationMatrix, out ray.Direction);
|
Vector3.TransformNormal(ray.Direction, 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(ref plane, out intersection))
|
if (ray.Intersects(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(ref plane, out intersection))
|
if (ray.Intersects(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(ref plane, out intersection))
|
if (ray.Intersects(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(ref planeYZ, out intersection))
|
if (ray.Intersects(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(ref planeXY, out intersection))
|
if (ray.Intersects(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(ref planeZX, out intersection))
|
if (ray.Intersects(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(ref plane, out intersection))
|
if (ray.Intersects(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(ref viewDir, ref dir, out float dot);
|
Float3.Dot(viewDir, dir, out float dot);
|
||||||
if (dot < 0.0f)
|
if (dot < 0.0f)
|
||||||
delta *= -1;
|
delta *= -1;
|
||||||
|
|
||||||
Quaternion.RotationAxis(ref dir, delta, out _rotationDelta);
|
Quaternion.RotationAxis(dir, delta, out _rotationDelta);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ namespace FlaxEditor
|
|||||||
{
|
{
|
||||||
foreach (var widget in _widgets)
|
foreach (var widget in _widgets)
|
||||||
{
|
{
|
||||||
if (widget.Bounds.Contains(ref location))
|
if (widget.Bounds.Contains(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(ref location))
|
if (widget.Bounds.Contains(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(ref viewRect);
|
Render2D.PushClip(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(ref _cachedTransform);
|
Render2D.PushTransform(_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(ref ul, ref bl, 0.5f, out var el);
|
Float2.Lerp(ul, bl, 0.5f, out var el);
|
||||||
Float2.Lerp(ref ur, ref br, 0.5f, out var er);
|
Float2.Lerp(ur, br, 0.5f, out var er);
|
||||||
Float2.Lerp(ref ul, ref ur, 0.5f, out var eu);
|
Float2.Lerp(ul, ur, 0.5f, out var eu);
|
||||||
Float2.Lerp(ref bl, ref br, 0.5f, out var eb);
|
Float2.Lerp(bl, 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(ref mousePos))
|
if (rect.Contains(mousePos))
|
||||||
{
|
{
|
||||||
Render2D.FillRectangle(rect, style.Foreground);
|
Render2D.FillRectangle(rect, style.Foreground);
|
||||||
Render2D.DrawRectangle(rect, style.SelectionBorder);
|
Render2D.DrawRectangle(rect, style.SelectionBorder);
|
||||||
|
|||||||
@@ -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(ref worldSpaceLocation, ref _viewProjection, out var projected);
|
_viewport.Project(worldSpaceLocation, _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(ref bounds);
|
return _frustum.Contains(bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -402,10 +402,11 @@ 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)
|
if (!window || window->IsClosed())
|
||||||
continue;
|
continue;
|
||||||
switch (e.Type)
|
switch (e.Type)
|
||||||
{
|
{
|
||||||
@@ -435,12 +436,14 @@ 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;
|
||||||
|
|||||||
@@ -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));
|
return (Window*)MUtils::Unbox<void*>(method->Invoke(GetManagedInstance(), nullptr, nullptr), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
return MUtils::Unbox<bool>(Internal_CanReloadScripts->Invoke(GetManagedInstance(), nullptr, nullptr), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
return MUtils::Unbox<bool>(Internal_CanAutoBuildCSG->Invoke(GetManagedInstance(), nullptr, nullptr), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
return MUtils::Unbox<bool>(Internal_CanAutoBuildNavMesh->Invoke(GetManagedInstance(), nullptr, nullptr), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ManagedEditor::HasGameViewportFocus() const
|
bool ManagedEditor::HasGameViewportFocus() const
|
||||||
@@ -397,7 +397,8 @@ bool ManagedEditor::HasGameViewportFocus() const
|
|||||||
Internal_HasGameViewportFocus = GetClass()->GetMethod("Internal_HasGameViewportFocus");
|
Internal_HasGameViewportFocus = GetClass()->GetMethod("Internal_HasGameViewportFocus");
|
||||||
ASSERT(Internal_HasGameViewportFocus);
|
ASSERT(Internal_HasGameViewportFocus);
|
||||||
}
|
}
|
||||||
result = MUtils::Unbox<bool>(Internal_HasGameViewportFocus->Invoke(GetManagedInstance(), nullptr, nullptr));
|
auto invk = Internal_HasGameViewportFocus->Invoke(GetManagedInstance(), nullptr, nullptr);
|
||||||
|
result = MUtils::Unbox<bool>(invk, true);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -495,7 +496,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));
|
return MUtils::Unbox<bool>(Internal_OnAppExit->Invoke(GetManagedInstance(), nullptr, nullptr), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedEditor::RequestStartPlayOnEditMode()
|
void ManagedEditor::RequestStartPlayOnEditMode()
|
||||||
|
|||||||
@@ -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"))
|
else if (path.EndsWith(".cpp") || path.EndsWith(".h") || path.EndsWith(".c") || path.EndsWith(".hpp"))
|
||||||
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);
|
||||||
|
|||||||
@@ -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"))
|
if (!targetLocation.CanHaveScripts && (extension == ".cs" || extension == ".cpp" || extension == ".h" || extension == ".c" || extension == ".hpp"))
|
||||||
{
|
{
|
||||||
// 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));
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ namespace FlaxEditor.Modules
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void OnPlayBegin()
|
public override void OnPlayBeginning()
|
||||||
{
|
{
|
||||||
Editor.Windows.FlashMainWindow();
|
Editor.Windows.FlashMainWindow();
|
||||||
|
|
||||||
|
|||||||
@@ -334,6 +334,9 @@ namespace FlaxEditor.Modules.SourceCodeEditing
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (editor == null)
|
||||||
|
editor = Editor.Instance.CodeEditing.Editors[0];
|
||||||
|
|
||||||
Editor.Instance.CodeEditing.SelectedEditor = editor;
|
Editor.Instance.CodeEditing.SelectedEditor = editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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_WINDOW
|
#if PLATFORM_WINDOWS
|
||||||
// Favor the newest Visual Studio
|
// Favor the newest Visual Studio
|
||||||
for (int i = (int)CodeEditorTypes.VS2019; i >= (int)CodeEditorTypes.VS2008; i--)
|
for (int i = (int)CodeEditorTypes.VS2026; 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 => null;
|
public string GenerateProjectCustomArgs => _currentEditor?.GenerateProjectCustomArgs;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void OpenSolution()
|
public void OpenSolution()
|
||||||
|
|||||||
@@ -22,71 +22,14 @@ namespace FlaxEditor.Modules.SourceCodeEditing
|
|||||||
public InBuildSourceCodeEditor(CodeEditorTypes type)
|
public InBuildSourceCodeEditor(CodeEditorTypes type)
|
||||||
{
|
{
|
||||||
Type = type;
|
Type = type;
|
||||||
switch (type)
|
Name = CodeEditingManager.GetName(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
|
public string GenerateProjectCustomArgs => CodeEditingManager.GetGenerateProjectCustomArgs(Type);
|
||||||
{
|
|
||||||
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()
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ 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;
|
||||||
@@ -29,6 +28,40 @@ 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;
|
||||||
@@ -144,6 +177,11 @@ 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>
|
||||||
@@ -426,19 +464,11 @@ 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;
|
||||||
|
|
||||||
// Add dummy control for drawing the main window borders if using a custom style
|
mainWindow.PerformLayout(true);
|
||||||
#if PLATFORM_WINDOWS
|
|
||||||
if (!Editor.Options.Options.Interface.UseNativeWindowSystem)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
mainWindow.AddChild(new CustomWindowBorderControl
|
|
||||||
{
|
|
||||||
Size = Float2.Zero,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitViewportScaleOptions()
|
private void InitViewportScaleOptions()
|
||||||
@@ -510,23 +540,6 @@ 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()
|
||||||
{
|
{
|
||||||
@@ -558,13 +571,6 @@ 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);
|
||||||
@@ -618,10 +624,12 @@ namespace FlaxEditor.Modules
|
|||||||
|
|
||||||
private void InitMainMenu(RootControl mainWindow)
|
private void InitMainMenu(RootControl mainWindow)
|
||||||
{
|
{
|
||||||
MainMenu = new MainMenu(mainWindow)
|
MainMenu = new MainMenu()
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|
||||||
@@ -763,6 +771,20 @@ 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;
|
||||||
@@ -1183,6 +1205,7 @@ 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;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ 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;
|
||||||
@@ -758,17 +757,19 @@ 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 (!Editor.Instance.Options.Options.Interface.UseNativeWindowSystem)
|
if (Utilities.Utils.UseCustomWindowDecorations(isMainWindow: true))
|
||||||
{
|
{
|
||||||
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
|
||||||
}
|
}
|
||||||
#elif PLATFORM_LINUX
|
#if PLATFORM_LINUX && !PLATFORM_SDL
|
||||||
settings.HasBorder = false;
|
settings.HasBorder = false;
|
||||||
#endif
|
#endif
|
||||||
MainWindow = Platform.CreateWindow(ref settings);
|
MainWindow = Platform.CreateWindow(ref settings);
|
||||||
|
|||||||
@@ -179,6 +179,34 @@ 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>
|
||||||
@@ -268,7 +296,14 @@ 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_WINDOWS
|
#if PLATFORM_SDL
|
||||||
|
/// <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>
|
||||||
@@ -277,7 +312,7 @@ namespace FlaxEditor.Options
|
|||||||
public bool UseNativeWindowSystem { get; set; } = false;
|
public bool UseNativeWindowSystem { get; set; } = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PLATFORM_WINDOWS
|
#if PLATFORM_SDL || 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>
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ namespace FlaxEditor.SceneGraph
|
|||||||
}
|
}
|
||||||
|
|
||||||
var center = _actor.Transform.Translation;
|
var center = _actor.Transform.Translation;
|
||||||
ViewportIconsRenderer.GetBounds(ref center, ref ray.Ray.Position, out var sphere);
|
ViewportIconsRenderer.GetBounds(center, ray.Ray.Position, out var sphere);
|
||||||
return CollisionsHelper.RayIntersectsSphere(ref ray.Ray, ref sphere, out distance);
|
return CollisionsHelper.RayIntersectsSphere(ray.Ray, sphere, out distance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(ref position, ref skinningMatrices[indices[0]], out Float3 pos0);
|
Float3.Transform(position, skinningMatrices[indices[0]], out Float3 pos0);
|
||||||
Float3.Transform(ref position, ref skinningMatrices[indices[1]], out Float3 pos1);
|
Float3.Transform(position, skinningMatrices[indices[1]], out Float3 pos1);
|
||||||
Float3.Transform(ref position, ref skinningMatrices[indices[2]], out Float3 pos2);
|
Float3.Transform(position, skinningMatrices[indices[2]], out Float3 pos2);
|
||||||
Float3.Transform(ref position, ref skinningMatrices[indices[3]], out Float3 pos3);
|
Float3.Transform(position, 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(ref boneLocalBounds.Minimum, ref pos, out boneLocalBounds.Minimum);
|
Vector3.Min(boneLocalBounds.Minimum, pos, out boneLocalBounds.Minimum);
|
||||||
Vector3.Max(ref boneLocalBounds.Maximum, ref pos, out boneLocalBounds.Maximum);
|
Vector3.Max(boneLocalBounds.Maximum, 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(ref bk, ref matrix, out Float3 bkA);
|
Float3.Transform(bk, matrix, out Float3 bkA);
|
||||||
bk = bkA / bkLength;
|
bk = bkA / bkLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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, ref ray.Ray, out distance, out normal);
|
return Brush.Intersects(Index, 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(ref ray.Ray))
|
if (((BoxBrush)_actor).OrientedBox.Intersects(ray.Ray))
|
||||||
{
|
{
|
||||||
for (int i = 0; i < ChildNodes.Count; i++)
|
for (int i = 0; i < ChildNodes.Count; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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(ref ray.Ray, out distance);
|
return sphere.Intersects(ray.Ray, out distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace FlaxEditor.SceneGraph.Actors
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Camera.Internal_IntersectsItselfEditor(FlaxEngine.Object.GetUnmanagedPtr(_actor), ref ray.Ray, out distance);
|
return Camera.Internal_IntersectsItselfEditor(FlaxEngine.Object.GetUnmanagedPtr(_actor), ray.Ray, out distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -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, ref value);
|
set => Actor.SetInstanceTransform(Index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -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(ref ray.Ray, out distance);
|
return sphere.Intersects(ray.Ray, out distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -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(ref ray.Ray, out distance);
|
return new BoundingSphere(pos, nodeSize).Intersects(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(ref ray.Ray, out distance);
|
return new BoundingSphere(pos, tangentSize).Intersects(ray.Ray, out distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnDebugDraw(ViewportDebugDrawData data)
|
public override void OnDebugDraw(ViewportDebugDrawData data)
|
||||||
|
|||||||
@@ -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(ref translation, ref viewPosition, ref up, ref viewDirection, out m2);
|
Matrix.Billboard(translation, viewPosition, up, viewDirection, out m2);
|
||||||
Matrix.Multiply(ref m1, ref m2, out m3);
|
Matrix.Multiply(m1, m2, out m3);
|
||||||
Matrix.Scaling(ref transform.Scale, out m1);
|
Matrix.Scaling(transform.Scale, out m1);
|
||||||
Matrix.Multiply(ref m1, ref m3, out world);
|
Matrix.Multiply(m1, m3, out world);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
transform.GetWorld(out m2);
|
transform.GetWorld(out m2);
|
||||||
Matrix.Multiply(ref m1, ref m2, out world);
|
Matrix.Multiply(m1, 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(ref ray.Ray, out distance);
|
return bounds.Intersects(ray.Ray, out distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -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(ref pointLocal, ref v);
|
var distance = Float3.DistanceSquared(pointLocal, v);
|
||||||
if (distance <= minDistance)
|
if (distance <= minDistance)
|
||||||
{
|
{
|
||||||
hit = true;
|
hit = true;
|
||||||
|
|||||||
@@ -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(ref ray.Ray, out distance);
|
return uiCanvas.Bounds.Intersects(ray.Ray, out distance);
|
||||||
|
|
||||||
distance = 0;
|
distance = 0;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -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(ref sphere, ref childSphere, out sphere);
|
BoundingSphere.Merge(sphere, childSphere, out sphere);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,34 @@ 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);
|
||||||
|
|||||||
@@ -109,9 +109,18 @@ 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>
|
||||||
@@ -169,6 +178,20 @@ 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>
|
||||||
|
|||||||
@@ -257,12 +257,17 @@ 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(TEXT("-vs2022"));
|
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
@@ -290,7 +295,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(TEXT("-vs2022"));
|
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open solution
|
// Open solution
|
||||||
@@ -312,5 +317,5 @@ void RiderCodeEditor::OpenSolution()
|
|||||||
|
|
||||||
void RiderCodeEditor::OnFileAdded(const String& path)
|
void RiderCodeEditor::OnFileAdded(const String& path)
|
||||||
{
|
{
|
||||||
ScriptsBuilder::GenerateProject();
|
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ 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;
|
||||||
|
|||||||
@@ -148,12 +148,17 @@ 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();
|
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open file
|
// Open file
|
||||||
@@ -172,7 +177,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();
|
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open solution
|
// Open solution
|
||||||
@@ -187,7 +192,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();
|
ScriptsBuilder::GenerateProject(GetGenerateProjectCustomArgs());
|
||||||
return;
|
return;
|
||||||
if (!FileSystem::FileExists(_solutionPath))
|
if (!FileSystem::FileExists(_solutionPath))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ 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;
|
||||||
|
|||||||
@@ -128,6 +128,11 @@ 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
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ 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;
|
||||||
|
|||||||
@@ -121,9 +121,13 @@ 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();
|
||||||
|
|||||||
@@ -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(ref _debugPos, ref prev) / new Float2(_rangeX.Absolute.ValuesSum, _rangeY.Absolute.ValuesSum).Length * 100.0f) * debugMaxSize + 1.0f;
|
float debugScale = Mathf.Saturate(Float2.Distance(_debugPos, 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(ref _triangles[i + 0], ref pos);
|
var is0 = Float2.NearEqual(_triangles[i + 0], pos);
|
||||||
var is1 = Float2.NearEqual(ref _triangles[i + 1], ref pos);
|
var is1 = Float2.NearEqual(_triangles[i + 1], pos);
|
||||||
var is2 = Float2.NearEqual(ref _triangles[i + 2], ref pos);
|
var is2 = Float2.NearEqual(_triangles[i + 2], 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(ref highlightColor);
|
Render2D.PushTint(highlightColor);
|
||||||
Render2D.DrawTriangles(_selectedTriangles, _selectedColors);
|
Render2D.DrawTriangles(_selectedTriangles, _selectedColors);
|
||||||
Render2D.PopTint();
|
Render2D.PopTint();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(ref location))
|
if (_headerRect.Contains(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(ref clientArea);
|
Render2D.PushClip(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(ref location);
|
return _dragAreaRect.MakeOffsetted(Location).Contains(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(ref location))
|
if (button == MouseButton.Left && !_dragAreaRect.Contains(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(ref bounds, ref startPos, out endPos);
|
CollisionsHelper.ClosestPointRectanglePoint(bounds, 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(ref mousePosition))
|
if (!TransitionsRectangle.Contains(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(ref mousePosition))
|
if (t.Bounds.Contains(mousePosition))
|
||||||
{
|
{
|
||||||
CollisionsHelper.ClosestPointPointLine(ref mousePosition, ref t.StartPos, ref t.EndPos, out var point);
|
CollisionsHelper.ClosestPointPointLine(mousePosition, t.StartPos, t.EndPos, out var point);
|
||||||
if (Float2.DistanceSquared(ref mousePosition, ref point) < 25.0f)
|
if (Float2.DistanceSquared(mousePosition, 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(ref mousePosition))
|
if (!TransitionsRectangle.Contains(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(ref mousePosition))
|
if (t.Bounds.Contains(mousePosition))
|
||||||
{
|
{
|
||||||
CollisionsHelper.ClosestPointPointLine(ref mousePosition, ref t.StartPos, ref t.EndPos, out var point);
|
CollisionsHelper.ClosestPointPointLine(mousePosition, t.StartPos, t.EndPos, out var point);
|
||||||
if (Float2.DistanceSquared(ref mousePosition, ref point) < 25.0f)
|
if (Float2.DistanceSquared(mousePosition, 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(ref dir, out var nrm);
|
Float2.Perpendicular(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(ref startPos, ref endPos, out t.Bounds);
|
Rectangle.FromPoints(startPos, 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(ref TransitionsRectangle, ref Transitions[i].Bounds, out TransitionsRectangle);
|
Rectangle.Union(TransitionsRectangle, 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(ref clientArea);
|
Render2D.PushClip(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(ref location);
|
return _dragAreaRect.MakeOffsetted(Location).Contains(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(ref location) || _closeButtonRect.Contains(ref location))
|
if (_renameButtonRect.Contains(location) || _closeButtonRect.Contains(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(ref location))
|
if (button == MouseButton.Left && !_dragAreaRect.Contains(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(ref mousePosition);
|
var isMouseOver = t.Bounds.Contains(mousePosition);
|
||||||
if (isMouseOver)
|
if (isMouseOver)
|
||||||
{
|
{
|
||||||
CollisionsHelper.ClosestPointPointLine(ref mousePosition, ref t.StartPos, ref t.EndPos, out var point);
|
CollisionsHelper.ClosestPointPointLine(mousePosition, t.StartPos, t.EndPos, out var point);
|
||||||
isMouseOver = Float2.DistanceSquared(ref mousePosition, ref point) < 25.0f;
|
isMouseOver = Float2.DistanceSquared(mousePosition, 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(ref location))
|
if (_renameButtonRect.Contains(location))
|
||||||
{
|
{
|
||||||
StartRenaming();
|
StartRenaming();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -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(ref location) && Surface.CanEdit)
|
if (_nameField.Bounds.Contains(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(ref location))
|
if (button == MouseButton.Left && _headerRect.Contains(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(ref location))
|
if (button == MouseButton.Left && _headerRect.Contains(location))
|
||||||
{
|
{
|
||||||
OnEditSignature();
|
OnEditSignature();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -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(ref location);
|
return base.CanSelect(ref location) && !_resizeButtonRect.MakeOffsetted(Location).Contains(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(ref location) && Surface.CanEdit)
|
if (button == MouseButton.Left && _resizeButtonRect.Contains(location) && Surface.CanEdit)
|
||||||
{
|
{
|
||||||
// Start sliding
|
// Start sliding
|
||||||
_isResizing = true;
|
_isResizing = true;
|
||||||
|
|||||||
@@ -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(ref location))
|
if (button == MouseButton.Left && _arrangeButtonRect.Contains(location))
|
||||||
{
|
{
|
||||||
_arrangeButtonInUse = true;
|
_arrangeButtonInUse = true;
|
||||||
Focus();
|
Focus();
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ namespace FlaxEditor.Surface.Archetypes
|
|||||||
|
|
||||||
// Header
|
// Header
|
||||||
var headerColor = style.BackgroundHighlighted;
|
var headerColor = style.BackgroundHighlighted;
|
||||||
if (_headerRect.Contains(ref _mousePosition))
|
if (_headerRect.Contains(_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);
|
||||||
|
|||||||
@@ -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(ref arrowTransform);
|
Render2D.PushTransform(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(ref location, ref _startMovePos) > 25.0f)
|
if (_isMoving && Float2.DistanceSquared(location, _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(ref _mousePosition) && !Surface.IsLeftMouseButtonDown && !Surface.IsRightMouseButtonDown && !Surface.IsPrimaryMenuOpened;
|
protected override bool ShowTooltip => !string.IsNullOrEmpty(TooltipText) && _localBounds.Contains(_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(ref location) && ShowTooltip;
|
return _localBounds.Contains(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(ref location);
|
return new Rectangle(Location, DefaultSize).Contains(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(ref location); // Inner area for connecting, outer area for moving
|
_isMouseInConnectingBounds = IsMouseOver && _localBounds.MakeExpanded(ConnectingBounds).Contains(location); // Inner area for connecting, outer area for moving
|
||||||
if (!_isMouseInConnectingBounds && !_isMouseDown)
|
if (!_isMouseInConnectingBounds && !_isMouseDown)
|
||||||
Cursor = CursorType.SizeAll;
|
Cursor = CursorType.SizeAll;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -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(ref point, ref oldp, ref p, out var result);
|
CollisionsHelper.ClosestPointPointLine(point, oldp, 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(ref p0, ref p1, alpha, out var p01);
|
Float2.Lerp(p0, p1, alpha, out var p01);
|
||||||
Float2.Lerp(ref p1, ref p2, alpha, out var p12);
|
Float2.Lerp(p1, p2, alpha, out var p12);
|
||||||
Float2.Lerp(ref p2, ref p3, alpha, out var p23);
|
Float2.Lerp(p2, p3, alpha, out var p23);
|
||||||
Float2.Lerp(ref p01, ref p12, alpha, out var p012);
|
Float2.Lerp(p01, p12, alpha, out var p012);
|
||||||
Float2.Lerp(ref p12, ref p23, alpha, out var p123);
|
Float2.Lerp(p12, p23, alpha, out var p123);
|
||||||
Float2.Lerp(ref p012, ref p123, alpha, out result);
|
Float2.Lerp(p012, p123, alpha, out result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -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(ref location) && !_resizeButtonRect.MakeOffsetted(Location).Contains(ref location);
|
return _headerRect.MakeOffsetted(Location).Contains(location) && !_resizeButtonRect.MakeOffsetted(Location).Contains(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool IsSelectionIntersecting(ref Rectangle selectionRect)
|
public override bool IsSelectionIntersecting(ref Rectangle selectionRect)
|
||||||
{
|
{
|
||||||
return _headerRect.MakeOffsetted(Location).Intersects(ref selectionRect);
|
return _headerRect.MakeOffsetted(Location).Intersects(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(ref location) || _resizeButtonRect.Contains(ref location);
|
return _headerRect.Contains(location) || _resizeButtonRect.Contains(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(ref location) && Surface.CanEdit)
|
if (button == MouseButton.Left && _resizeButtonRect.Contains(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(ref location) && Surface.CanEdit)
|
if (_headerRect.Contains(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(ref location) && Surface.CanEdit)
|
if (_closeButtonRect.Contains(location) && Surface.CanEdit)
|
||||||
{
|
{
|
||||||
Surface.Delete(this);
|
Surface.Delete(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
if (_colorButtonRect.Contains(ref location) && Surface.CanEdit)
|
if (_colorButtonRect.Contains(location) && Surface.CanEdit)
|
||||||
{
|
{
|
||||||
ColorValueBox.ShowPickColorDialog?.Invoke(this, Color, OnColorChanged);
|
ColorValueBox.ShowPickColorDialog?.Invoke(this, Color, OnColorChanged);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -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(ref selectionRect);
|
return Bounds.Intersects(selectionRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -868,7 +868,7 @@ namespace FlaxEditor.Surface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override bool ShowTooltip => base.ShowTooltip && _headerRect.Contains(ref _mousePosition) && !Surface.IsLeftMouseButtonDown && !Surface.IsRightMouseButtonDown && !Surface.IsPrimaryMenuOpened;
|
protected override bool ShowTooltip => base.ShowTooltip && _headerRect.Contains(_mousePosition) && !Surface.IsLeftMouseButtonDown && !Surface.IsRightMouseButtonDown && !Surface.IsPrimaryMenuOpened;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnShowTooltip(out string text, out Float2 location, out Rectangle area)
|
public override bool OnShowTooltip(out string text, out Float2 location, out Rectangle area)
|
||||||
@@ -898,13 +898,13 @@ namespace FlaxEditor.Surface
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool OnTestTooltipOverControl(ref Float2 location)
|
public override bool OnTestTooltipOverControl(ref Float2 location)
|
||||||
{
|
{
|
||||||
return _headerRect.Contains(ref location) && ShowTooltip && !Surface.IsConnecting && !Surface.IsSelecting;
|
return _headerRect.Contains(location) && ShowTooltip && !Surface.IsConnecting && !Surface.IsSelecting;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override bool CanSelect(ref Float2 location)
|
public override bool CanSelect(ref Float2 location)
|
||||||
{
|
{
|
||||||
return _headerRect.MakeOffsetted(Location).Contains(ref location);
|
return _headerRect.MakeOffsetted(Location).Contains(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -1056,7 +1056,7 @@ namespace FlaxEditor.Surface
|
|||||||
|
|
||||||
// Header
|
// Header
|
||||||
var headerColor = style.BackgroundHighlighted;
|
var headerColor = style.BackgroundHighlighted;
|
||||||
if (_headerRect.Contains(ref _mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting)
|
if (_headerRect.Contains(_mousePosition) && !Surface.IsConnecting && !Surface.IsSelecting)
|
||||||
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);
|
||||||
@@ -1099,7 +1099,7 @@ namespace FlaxEditor.Surface
|
|||||||
if (base.OnMouseDown(location, button))
|
if (base.OnMouseDown(location, button))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (button == MouseButton.Left && (Archetype.Flags & NodeFlags.NoCloseButton) == 0 && _closeButtonRect.Contains(ref location))
|
if (button == MouseButton.Left && (Archetype.Flags & NodeFlags.NoCloseButton) == 0 && _closeButtonRect.Contains(location))
|
||||||
return true;
|
return true;
|
||||||
if (button == MouseButton.Right)
|
if (button == MouseButton.Right)
|
||||||
mouseDownMousePosition = Input.Mouse.Position;
|
mouseDownMousePosition = Input.Mouse.Position;
|
||||||
@@ -1115,7 +1115,7 @@ namespace FlaxEditor.Surface
|
|||||||
|
|
||||||
// Close/ delete
|
// Close/ delete
|
||||||
bool canDelete = !Surface.IsConnecting && !Surface.WasSelecting && !Surface.WasMovingSelection;
|
bool canDelete = !Surface.IsConnecting && !Surface.WasSelecting && !Surface.WasMovingSelection;
|
||||||
if (button == MouseButton.Left && canDelete && (Archetype.Flags & NodeFlags.NoCloseButton) == 0 && _closeButtonRect.Contains(ref location))
|
if (button == MouseButton.Left && canDelete && (Archetype.Flags & NodeFlags.NoCloseButton) == 0 && _closeButtonRect.Contains(location))
|
||||||
{
|
{
|
||||||
Surface.Delete(this);
|
Surface.Delete(this);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user