diff --git a/Source/Editor/CustomEditorWindow.cs b/Source/Editor/CustomEditorWindow.cs
index 4a94e0a34..4711ee9b2 100644
--- a/Source/Editor/CustomEditorWindow.cs
+++ b/Source/Editor/CustomEditorWindow.cs
@@ -1,6 +1,5 @@
// Copyright (c) Wojciech Figat. All rights reserved.
-using System;
using FlaxEditor.CustomEditors;
using FlaxEditor.GUI.Docking;
using FlaxEditor.Windows;
@@ -92,19 +91,7 @@ namespace FlaxEditor
Editor.Instance.Windows.AddToRestore(this);
}
Window.Close(ClosingReason.ScriptsReload);
- }
-
- ///
- /// Reattaches the window control to existing floating window.
- ///
- /// The window handle.
- /// Initial window state.
- /// The panel to dock to, if any.
- /// Only used if is set. If true the window will be selected after docking it.
- /// The splitter value to use if toDock is not null. If not specified, a default value will be used.
- public void Restore(IntPtr windowHandle, DockState state = DockState.Float, DockPanel toDock = null, bool autoSelect = true, float? splitterValue = null)
- {
- _win.Restore(windowHandle, state, toDock, autoSelect, splitterValue);
+ Window.Dispose();
}
///
diff --git a/Source/Editor/GUI/Docking/DockWindow.cs b/Source/Editor/GUI/Docking/DockWindow.cs
index bf08695d8..a6c98a1f6 100644
--- a/Source/Editor/GUI/Docking/DockWindow.cs
+++ b/Source/Editor/GUI/Docking/DockWindow.cs
@@ -1,9 +1,7 @@
// Copyright (c) Wojciech Figat. All rights reserved.
-using System;
using System.Xml;
using System.Globalization;
-using System.Linq;
using FlaxEngine;
using FlaxEngine.Assertions;
using FlaxEngine.GUI;
@@ -234,46 +232,6 @@ namespace FlaxEditor.GUI.Docking
}
}
- ///
- /// Reattaches the window control to existing floating window.
- ///
- /// The window handle.
- /// Initial window state.
- /// Panel to dock to it.
- /// Only used if is set. If true the window will be selected after docking it.
- /// Only used if is set. The splitter value to use. If not specified, a default value will be used.
- public void Restore(IntPtr windowHandle, DockState state = DockState.Float, DockPanel toDock = null, bool autoSelect = true, float? splitterValue = null)
- {
- if (state != DockState.Float)
- {
- Show(state, toDock, autoSelect, splitterValue);
- return;
- }
-
- Undock();
-
- // Find the existing window and remove all controls from it
- var window = Editor.GetWindows().First(x => x.NativePtr == windowHandle);
- var windowGUI = window.GUI;
- while (windowGUI.Children.Count > 0)
- windowGUI.Children[^1].Dispose();
- windowGUI.EndTrackingMouse();
-
- // Create dock panel for the window
- var dockPanel = new FloatWindowDockPanel(_masterPanel, windowGUI);
- dockPanel.DockWindowInternal(DockState.DockFill, this);
-
- // Perform layout
- Visible = true;
- windowGUI.UnlockChildrenRecursive();
- windowGUI.PerformLayout();
-
- OnShow();
-
- // Perform layout again
- windowGUI.PerformLayout();
- }
-
///
/// Shows the window.
///
@@ -374,12 +332,6 @@ namespace FlaxEditor.GUI.Docking
}
else
{
- if (reason == ClosingReason.ScriptsReload && _dockedTo is FloatWindowDockPanel floatPanel)
- {
- // Unlink the window to keep it alive during scripts reload
- floatPanel.UnlinkWindow();
- }
-
// Undock
Undock();
diff --git a/Source/Editor/GUI/Docking/FloatWindowDockPanel.cs b/Source/Editor/GUI/Docking/FloatWindowDockPanel.cs
index f8eb26ded..211715f5b 100644
--- a/Source/Editor/GUI/Docking/FloatWindowDockPanel.cs
+++ b/Source/Editor/GUI/Docking/FloatWindowDockPanel.cs
@@ -270,8 +270,8 @@ namespace FlaxEditor.GUI.Docking
public override void OnDestroy()
{
_masterPanel?.FloatingPanels.Remove(this);
-
UnlinkWindow();
+
base.OnDestroy();
}
}
diff --git a/Source/Editor/Modules/WindowsModule.cs b/Source/Editor/Modules/WindowsModule.cs
index 8074ab814..1a03c7c57 100644
--- a/Source/Editor/Modules/WindowsModule.cs
+++ b/Source/Editor/Modules/WindowsModule.cs
@@ -4,7 +4,6 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
-using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
@@ -34,12 +33,11 @@ namespace FlaxEditor.Modules
private float _projectIconScreenshotTimeout = -1;
private string _windowsLayoutPath;
- private class WindowRestoreData
+ private struct WindowRestoreData
{
public string AssemblyName;
public string TypeName;
- public IntPtr WindowHandle;
public DockState DockState;
public DockPanel DockedTo;
public int DockedTabIndex;
@@ -47,10 +45,20 @@ namespace FlaxEditor.Modules
public bool SelectOnShow = false;
+ public bool Maximize;
+ public bool Minimize;
+ public Float2 FloatSize;
+ public Float2 FloatPosition;
+
public Guid AssetItemID;
+
+ // Constructor, to allow for default values
+ public WindowRestoreData()
+ {
+ }
}
- private readonly Dictionary _restoreWindows = new();
+ private readonly List _restoreWindows = new List();
///
/// The main editor window.
@@ -814,14 +822,10 @@ namespace FlaxEditor.Modules
internal void AddToRestore(AssetEditorWindow win)
{
- var assetItemId = win.Item.ID;
- if (!_restoreWindows.TryGetValue(assetItemId, out var winData))
+ AddToRestore(win, win.GetType(), new WindowRestoreData
{
- winData = new WindowRestoreData();
- _restoreWindows.Add(assetItemId, winData);
- }
- winData.AssetItemID = assetItemId;
- AddToRestore(win, win.GetType(), winData);
+ AssetItemID = win.Item.ID,
+ });
}
internal void AddToRestore(CustomEditorWindow win)
@@ -832,65 +836,62 @@ namespace FlaxEditor.Modules
if (constructor == null || type.IsGenericType)
return;
- // TODO: Restore data for custom editors
- var assetItemId = Guid.NewGuid();
- if (!_restoreWindows.TryGetValue(assetItemId, out var winData))
- {
- winData = new WindowRestoreData();
- _restoreWindows.Add(assetItemId, winData);
- }
- winData.AssetItemID = assetItemId;
- AddToRestore(win.Window, type, winData);
+ AddToRestore(win.Window, type, new WindowRestoreData());
}
private void AddToRestore(EditorWindow win, Type type, WindowRestoreData winData)
{
+ // Ensure that this window is only selected following recompilation
+ // if it was the active tab in its dock panel. Otherwise, there is a
+ // risk of interrupting the user's workflow by potentially selecting
+ // background tabs.
var window = win.RootWindow?.Window;
var panel = win.ParentDockPanel;
- winData.AssemblyName = type.Assembly.GetName().Name;
- winData.TypeName = type.FullName;
- if (panel is FloatWindowDockPanel)
+ winData.SelectOnShow = panel.SelectedTab == win;
+ winData.DockedTabIndex = 0;
+ if (panel is FloatWindowDockPanel && window != null && panel.TabsCount == 1)
{
- // Populate data for other tabs now, the tab index may change after tab is destroyed
- if (winData.DockedTo == null)
- {
- for (int i = 0; i < panel.Tabs.Count; i++)
- {
- if (panel.Tabs[i] is AssetEditorWindow assetEditorWindow)
- {
- window ??= assetEditorWindow.RootWindow?.Window; // The window handle is sometimes missing in some tabs
- var assetItemId = assetEditorWindow.Item.ID;
- if (!_restoreWindows.TryGetValue(assetItemId, out var tabWinData))
- {
- tabWinData = new WindowRestoreData();
- _restoreWindows.Add(assetItemId, tabWinData);
- }
-
- tabWinData.DockedTabIndex = i;
- tabWinData.SelectOnShow = panel.SelectedTab == assetEditorWindow;
- tabWinData.DockState = DockState.DockFill;
- tabWinData.DockedTo = panel;
- }
- }
- winData.DockState = DockState.Float;
- winData.WindowHandle = window?.NativePtr ?? IntPtr.Zero;
- }
+ winData.DockState = DockState.Float;
+ winData.FloatPosition = window.Position;
+ winData.FloatSize = window.ClientSize;
+ winData.Maximize = window.IsMaximized;
+ winData.Minimize = window.IsMinimized;
+ winData.DockedTo = panel;
}
else
{
- winData.DockState = panel.TryGetDockState(out var splitterValue);
- winData.DockedTo = panel.ParentDockPanel;
- winData.SplitterValue = splitterValue;
+ for (int i = 0; i < panel.Tabs.Count; i++)
+ {
+ if (panel.Tabs[i] == win)
+ {
+ winData.DockedTabIndex = i;
+ break;
+ }
+ }
+ if (panel.TabsCount > 1)
+ {
+ winData.DockState = DockState.DockFill;
+ winData.DockedTo = panel;
+ }
+ else
+ {
+ winData.DockState = panel.TryGetDockState(out var splitterValue);
+ winData.DockedTo = panel.ParentDockPanel;
+ winData.SplitterValue = splitterValue;
+ }
}
+ winData.AssemblyName = type.Assembly.GetName().Name;
+ winData.TypeName = type.FullName;
+ _restoreWindows.Add(winData);
}
private void OnWorkspaceRebuilt()
{
- var assetEditorWindows = new Dictionary();
-
- // Create float windows first, then add docked windows in order of the tabs
- foreach (var (_, winData) in _restoreWindows)
+ // Go in reverse order to create floating Prefab windows first before docked windows
+ for (int i = _restoreWindows.Count - 1; i >= 0; i--)
{
+ var winData = _restoreWindows[i];
+
try
{
var assembly = Utils.GetAssemblyByName(winData.AssemblyName);
@@ -907,24 +908,75 @@ namespace FlaxEditor.Modules
var assetType = assetItem.GetType();
var ctor = type.GetConstructor(new Type[] { typeof(Editor), assetType });
var win = (AssetEditorWindow)ctor.Invoke(new object[] { Editor.Instance, assetItem });
- var previouslyDockedTo = winData.DockedTo;
- win.Restore(winData.WindowHandle, winData.DockState, winData.DockState != DockState.Float ? winData.DockedTo : null, winData.SelectOnShow, winData.SplitterValue);
+
+ win.Show(winData.DockState, winData.DockState != DockState.Float ? winData.DockedTo : null, winData.SelectOnShow, winData.SplitterValue);
if (winData.DockState == DockState.Float)
{
- // Update panel reference in other windows docked to this panel
- foreach (var key in _restoreWindows.Keys)
+ var window = win.RootWindow.Window;
+ window.Position = winData.FloatPosition;
+ if (winData.Maximize)
{
- ref var otherData = ref CollectionsMarshal.GetValueRefOrNullRef(_restoreWindows, key);
- if (otherData.DockedTo == previouslyDockedTo)
+ window.Maximize();
+ }
+ else if (winData.Minimize)
+ {
+ window.Minimize();
+ }
+ else
+ {
+ window.ClientSize = winData.FloatSize;
+ }
+
+ // Update panel reference in other windows docked to this panel
+ foreach (ref var otherData in CollectionsMarshal.AsSpan(_restoreWindows))
+ {
+ if (otherData.DockedTo == winData.DockedTo)
otherData.DockedTo = win.ParentDockPanel;
}
}
- assetEditorWindows.Add(winData.AssetItemID, win);
+ var panel = win.ParentDockPanel;
+ int currentTabIndex = 0;
+ for (int pi = 0; pi < panel.TabsCount; pi++)
+ {
+ if (panel.Tabs[pi] == win)
+ {
+ currentTabIndex = pi;
+ break;
+ }
+ }
+ while (currentTabIndex > winData.DockedTabIndex)
+ {
+ win.ParentDockPanel.MoveTabLeft(currentTabIndex);
+ currentTabIndex--;
+ }
+ while (currentTabIndex < winData.DockedTabIndex)
+ {
+ win.ParentDockPanel.MoveTabRight(currentTabIndex);
+ currentTabIndex++;
+ }
+ panel.PerformLayout(true);
}
else
{
var win = (CustomEditorWindow)Activator.CreateInstance(type);
- win.Restore(winData.WindowHandle, winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue);
+ win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue);
+ if (winData.DockState == DockState.Float)
+ {
+ var window = win.Window.RootWindow.Window;
+ window.Position = winData.FloatPosition;
+ if (winData.Maximize)
+ {
+ window.Maximize();
+ }
+ else if (winData.Minimize)
+ {
+ window.Minimize();
+ }
+ else
+ {
+ window.ClientSize = winData.FloatSize;
+ }
+ }
}
}
catch (Exception ex)
@@ -933,46 +985,6 @@ namespace FlaxEditor.Modules
Editor.LogWarning(string.Format("Failed to restore window {0} (assembly: {1})", winData.TypeName, winData.AssemblyName));
}
}
-
- // Reorder tabs to previous order
- foreach (var (_, winData) in _restoreWindows)
- {
- var win = assetEditorWindows.GetValueOrDefault(winData.AssetItemID);
- if (win == null)
- continue;
-
- var panel = win.ParentDockPanel;
- int currentTabIndex = 0;
- for (int pi = 0; pi < panel.TabsCount; pi++)
- {
- if (panel.Tabs[pi] == win)
- {
- currentTabIndex = pi;
- break;
- }
- }
- while (currentTabIndex > winData.DockedTabIndex)
- {
- win.ParentDockPanel.MoveTabLeft(currentTabIndex);
- currentTabIndex--;
- }
- while (currentTabIndex < winData.DockedTabIndex)
- {
- win.ParentDockPanel.MoveTabRight(currentTabIndex);
- currentTabIndex++;
- }
- }
-
- // Restore last selected tab
- foreach (var (_, winData) in _restoreWindows)
- {
- var win = assetEditorWindows.GetValueOrDefault(winData.AssetItemID);
- if (win != null && winData.SelectOnShow)
- {
- win.ParentDockPanel.SelectTab(win, false);
- win.ParentDockPanel.PerformLayout(true);
- }
- }
// Restored windows stole the focus from Editor
if (_restoreWindows.Count > 0)
diff --git a/Source/Editor/Windows/Assets/JsonAssetWindow.cs b/Source/Editor/Windows/Assets/JsonAssetWindow.cs
index 75acd74dd..5cbf78f2a 100644
--- a/Source/Editor/Windows/Assets/JsonAssetWindow.cs
+++ b/Source/Editor/Windows/Assets/JsonAssetWindow.cs
@@ -148,6 +148,7 @@ namespace FlaxEditor.Windows.Assets
protected override void OnScriptsReloadBegin()
{
base.OnScriptsReloadBegin();
+
Close(ClosingReason.ScriptsReload);
}