diff --git a/Source/Editor/Modules/WindowsModule.cs b/Source/Editor/Modules/WindowsModule.cs index fa7a04d9b..ba29bea4f 100644 --- a/Source/Editor/Modules/WindowsModule.cs +++ b/Source/Editor/Modules/WindowsModule.cs @@ -5,10 +5,12 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Reflection; +using System.Runtime.InteropServices; using System.Text; using System.Xml; using FlaxEditor.Content; using FlaxEditor.GUI.Dialogs; +using FlaxEditor.GUI.Docking; using FlaxEditor.Windows; using FlaxEditor.Windows.Assets; using FlaxEditor.Windows.Profiler; @@ -39,6 +41,7 @@ namespace FlaxEditor.Modules public DockState DockState; public DockPanel DockedTo; + public int DockedTabIndex; public float? SplitterValue = null; public bool SelectOnShow = false; @@ -48,6 +51,9 @@ namespace FlaxEditor.Modules public Float2 FloatSize; public Float2 FloatPosition; + public AssetItem Item; + public AssetItem Item2; + // Constructor, to allow for default values public WindowRestoreData() { @@ -807,6 +813,56 @@ namespace FlaxEditor.Modules Editor.StateMachine.StateChanged += OnEditorStateChanged; } + internal void AddToRestore(PrefabWindow win) + { + var type = win.GetType(); + var winData = new WindowRestoreData(); + var panel = win.ParentDockPanel; + + // Ensure that this window is only selected following recompilation + // if it was the active tab in its dock panel. Otherwise, there is a + // risk of interrupting the user's workflow by potentially selecting + // background tabs. + var window = win.RootWindow?.Window; + winData.SelectOnShow = panel.SelectedTab == win; + winData.DockedTabIndex = 0; + if (panel is FloatWindowDockPanel && window != null && panel.TabsCount == 1) + { + winData.DockState = DockState.Float; + winData.FloatPosition = window.Position; + winData.FloatSize = window.ClientSize; + winData.Maximize = window.IsMaximized; + winData.Minimize = window.IsMinimized; + winData.DockedTo = panel; + } + else + { + for (int i = 0; i < panel.Tabs.Count; i++) + { + if (panel.Tabs[i] == win) + { + winData.DockedTabIndex = i; + break; + } + } + if (panel.TabsCount > 1) + { + winData.DockState = DockState.DockFill; + winData.DockedTo = panel; + } + else + { + winData.DockState = panel.TryGetDockState(out var splitterValue); + winData.DockedTo = panel.ParentDockPanel; + winData.SplitterValue = splitterValue; + } + } + winData.AssemblyName = type.Assembly.GetName().Name; + winData.TypeName = type.FullName; + winData.Item = win.Item; + _restoreWindows.Add(winData); + } + internal void AddToRestore(CustomEditorWindow win) { var type = win.GetType(); @@ -839,7 +895,8 @@ namespace FlaxEditor.Modules { winData.DockState = DockState.DockFill; winData.DockedTo = panel; - }else + } + else { winData.DockState = panel.TryGetDockState(out var splitterValue); winData.DockedTo = panel.ParentDockPanel; @@ -853,36 +910,89 @@ namespace FlaxEditor.Modules private void OnScriptsReloadEnd() { - for (int i = 0; i < _restoreWindows.Count; i++) + // 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); - if (assembly != null) + if (assembly == null) + continue; + + var type = assembly.GetType(winData.TypeName); + if (type == null) + continue; + + if (type == typeof(PrefabWindow)) { - var type = assembly.GetType(winData.TypeName); - if (type != null) + var win = new PrefabWindow(Editor.Instance, winData.Item); + win.Show(winData.DockState, winData.DockState != DockState.Float ? winData.DockedTo : null, winData.SelectOnShow, winData.SplitterValue); + if (winData.DockState == DockState.Float) { - var win = (CustomEditorWindow)Activator.CreateInstance(type); - win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue); - if (winData.DockState == DockState.Float) + var window = win.RootWindow.Window; + window.Position = winData.FloatPosition; + if (winData.Maximize) { - 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; - } + window.Maximize(); + } + else if (winData.Minimize) + { + window.Minimize(); + } + else + { + window.ClientSize = winData.FloatSize; + } + + // Update panel reference in other windows docked to this panel + foreach (ref var otherData in CollectionsMarshal.AsSpan(_restoreWindows)) + { + if (otherData.DockedTo == winData.DockedTo) + otherData.DockedTo = win.ParentDockPanel; + } + } + var panel = win.ParentDockPanel; + int currentTabIndex = 0; + for (int pi = 0; pi < panel.TabsCount; pi++) + { + if (panel.Tabs[pi] == win) + { + currentTabIndex = pi; + break; + } + } + while (currentTabIndex > winData.DockedTabIndex) + { + win.ParentDockPanel.MoveTabLeft(currentTabIndex); + currentTabIndex--; + } + while (currentTabIndex < winData.DockedTabIndex) + { + win.ParentDockPanel.MoveTabRight(currentTabIndex); + currentTabIndex++; + } + } + else + { + var win = (CustomEditorWindow)Activator.CreateInstance(type); + win.Show(winData.DockState, winData.DockedTo, winData.SelectOnShow, winData.SplitterValue); + if (winData.DockState == DockState.Float) + { + var window = win.Window.RootWindow.Window; + window.Position = winData.FloatPosition; + if (winData.Maximize) + { + window.Maximize(); + } + else if (winData.Minimize) + { + window.Minimize(); + } + else + { + window.ClientSize = winData.FloatSize; } } } diff --git a/Source/Editor/Windows/Assets/PrefabWindow.cs b/Source/Editor/Windows/Assets/PrefabWindow.cs index 533735c93..120ffda57 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.cs @@ -194,7 +194,6 @@ namespace FlaxEditor.Windows.Assets Editor.Prefabs.PrefabApplied += OnPrefabApplied; ScriptsBuilder.ScriptsReloadBegin += OnScriptsReloadBegin; - ScriptsBuilder.ScriptsReloadEnd += OnScriptsReloadEnd; // Setup input actions InputActions.Add(options => options.Undo, () => @@ -311,24 +310,18 @@ namespace FlaxEditor.Windows.Assets } } + if (!IsHidden) + { + Editor.Instance.Windows.AddToRestore(this); + } + // Cleanup Deselect(); Graph.MainActor = null; _viewport.Prefab = null; _undo?.Clear(); // TODO: maybe don't clear undo? - } - private void OnScriptsReloadEnd() - { - _isScriptsReloading = false; - - if (_asset == null || !_asset.IsLoaded) - return; - - // Restore - OnPrefabOpened(); - _undo.Clear(); - ClearEditedFlag(); + Close(); } private void OnUndoEvent(IUndoAction action) @@ -547,7 +540,6 @@ namespace FlaxEditor.Windows.Assets { Editor.Prefabs.PrefabApplied -= OnPrefabApplied; ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin; - ScriptsBuilder.ScriptsReloadEnd -= OnScriptsReloadEnd; _undo.Dispose(); Graph.Dispose(); diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs index 618dd8564..8626f187c 100644 --- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs +++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs @@ -1146,12 +1146,6 @@ namespace FlaxEngine.Interop MethodInfo clearCacheMethod = TypeDescriptionProviderType?.Assembly.GetType("System.ComponentModel.ReflectionCachesUpdateHandler")?.GetMethod("ClearCache"); if (clearCacheMethod != null) clearCacheMethod.Invoke(null, new object[] { null }); - else - { - MethodInfo beforeUpdateMethod = TypeDescriptionProviderType?.Assembly.GetType("System.ComponentModel.ReflectionCachesUpdateHandler")?.GetMethod("BeforeUpdate"); - if (beforeUpdateMethod != null) - beforeUpdateMethod.Invoke(null, new object[] { null }); - } Type TypeDescriptorType = typeof(System.ComponentModel.TypeDescriptor);