dwelling acts 1 & 3
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

234 lines
8.7 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using ContainerWindow = UnityEngine.ScriptableObject;
using HostView = UnityEngine.ScriptableObject;
using View = UnityEngine.ScriptableObject;
namespace FullscreenEditor {
public class FullscreenWindow : FullscreenContainer {
[SerializeField] private RectOffset m_rectOffset;
[SerializeField] private RectOffset m_toolbarOffset;
[SerializeField] private bool m_createdByFullscreenOnPlay;
public RectOffset ClipOffset {
get { return m_rectOffset; }
set {
if(m_dst.View) {
m_rectOffset = value;
m_dst.View.InvokeMethod("SetPosition", value.Add(new Rect(Vector2.zero, Rect.size)));
}
}
}
internal bool CreatedByFullscreenOnPlay {
get { return m_createdByFullscreenOnPlay; }
set { m_createdByFullscreenOnPlay = value; }
}
public bool HasToolbarOffset { get { return ToolbarOffset != null; } }
public virtual RectOffset ToolbarOffset {
get {
if(m_toolbarOffset == null)
m_toolbarOffset = new RectOffset(0, 0, (int)FullscreenUtility.GetToolbarHeight(), 0);
return m_toolbarOffset;
}
}
private void SwapWindows(EditorWindow a, EditorWindow b) {
var parentA = a.GetFieldValue<View>("m_Parent");
var parentB = b.GetFieldValue<View>("m_Parent");
var containerA = parentA.GetPropertyValue<ContainerWindow>("window");
var containerB = parentB.GetPropertyValue<ContainerWindow>("window");
var selectedPaneA = parentA.GetPropertyValue<EditorWindow>("actualView");
var selectedPaneB = parentB.GetPropertyValue<EditorWindow>("actualView");
SetFreezeContainer(containerA, true);
SetFreezeContainer(containerB, true);
Logger.Debug("Swapping windows {0} and {1} @ {2} and {3}", a, b, parentA, parentB);
parentA.SetPropertyValue("actualView", b);
parentB.SetPropertyValue("actualView", a);
ReplaceDockAreaPane(parentA, a, b);
ReplaceDockAreaPane(parentB, b, a);
a.InvokeMethod("MakeParentsSettingsMatchMe");
b.InvokeMethod("MakeParentsSettingsMatchMe");
if(selectedPaneA != a)
parentA.SetPropertyValue("actualView", selectedPaneA);
if(selectedPaneB != b)
parentB.SetPropertyValue("actualView", selectedPaneB);
SetFreezeContainer(containerA, false);
SetFreezeContainer(containerB, false);
}
protected void ReplaceDockAreaPane(View dockArea, EditorWindow originalPane, EditorWindow newPane) {
if(dockArea.HasField("m_Panes")) {
var dockedPanes = dockArea.GetFieldValue<List<EditorWindow>>("m_Panes");
var dockIndex = dockedPanes.IndexOf(originalPane);
dockedPanes[dockIndex] = newPane;
}
}
public void SetToolbarStatus(bool toolbarVisible) {
if(!HasToolbarOffset)
return;
if(FullscreenPreferences.UseGlobalToolbarHiding)
return;
ClipOffset = toolbarVisible ? new RectOffset() : ToolbarOffset;
}
public override void Focus() {
var window = ActualViewPyramid.Window;
if(window)
window.Focus();
else
base.Focus();
}
public override bool IsFocused() {
return EditorWindow.focusedWindow && EditorWindow.focusedWindow == ActualViewPyramid.Window;
}
protected override void AfterOpening() {
base.AfterOpening();
Focus();
if(m_src.Window)
m_dst.Window.titleContent = m_src.Window.titleContent; // Copy the title of the window to the placeholder
SetToolbarStatus(FullscreenPreferences.ToolbarVisible); // Hide/show the toolbar
// macOS doesn't like fast things, so we'll wait a bit and do it again
// Looks like Linux does not like it too
After.Milliseconds(100d, () => SetToolbarStatus(FullscreenPreferences.ToolbarVisible));
var notificationWindow = ActualViewPyramid.Window;
After.Milliseconds(50d, () => {
if(!notificationWindow) // Might have been closed
return;
var menuItemPath = string.Empty;
if(notificationWindow.IsOfType(Types.GameView)) {
menuItemPath = Fullscreen
.GetAllFullscreen()
.Where(fs => fs.ActualViewPyramid.Window && fs.ActualViewPyramid.Window.IsOfType(Types.GameView))
.Count() > 1 ?
Shortcut.MOSAIC_PATH :
Shortcut.GAME_VIEW_PATH;
} else if(notificationWindow is SceneView)
menuItemPath = Shortcut.SCENE_VIEW_PATH;
else
menuItemPath = Shortcut.CURRENT_VIEW_PATH;
FullscreenUtility.ShowFullscreenExitNotification(notificationWindow, menuItemPath);
});
}
protected override void OnEnable() {
base.OnEnable();
FullscreenPreferences.ToolbarVisible.OnValueSaved += SetToolbarStatus;
}
protected override void OnDisable() {
base.OnDisable();
FullscreenPreferences.ToolbarVisible.OnValueSaved -= SetToolbarStatus;
}
internal void OpenWindow<T>(Rect rect, T window = null) where T : EditorWindow {
OpenWindow(rect, typeof(T), window);
}
internal void OpenWindow(Rect rect, Type type, EditorWindow window = null, bool disposableWindow = false) {
if(type == null)
throw new ArgumentNullException("type");
if(!type.IsOfType(typeof(EditorWindow)))
throw new ArgumentException("Type must be inherited from UnityEditor.EditorWindow", "type");
if(window is PlaceholderWindow) {
FullscreenUtility.ShowFullscreenNotification(window, "Wanna fullscreen the placeholder?\nSorry, not possible");
Logger.Debug("Tried to fullscreen a placeholder window");
return;
}
if(Fullscreen.GetFullscreenFromView(window)) {
FullscreenUtility.ShowFullscreenNotification(window, "You can't fullscreen a window already in fullscreen");
Logger.Debug("Tried to fullscreen a view already in fullscreen");
return;
}
if(window && window.HasProperty("isFullscreen") && window.GetPropertyValue<bool>("isFullscreen")) {
Logger.Debug("Tried to fullscreen a view already using Unity's built-in fullscreen");
window.ShowNotification(new GUIContent("This is a built-in fullscreen and not a Fullscreen Editor instance. Use Ctrl+Shift+F7 or Alt-F4 to close it."));
return;
}
BeforeOpening();
if(window)
m_src = new ViewPyramid(window);
var childWindow = window ?
(EditorWindow)CreateInstance<PlaceholderWindow>() :
(EditorWindow)CreateInstance(type); // Instantiate a new window for this fullscreen
m_dst = CreateFullscreenViewPyramid(rect, childWindow);
if(window) // We can't swap the src window if we didn't create a placeholder window
SwapWindows(m_src.Window, m_dst.Window);
Rect = rect;
if(disposableWindow && childWindow is PlaceholderWindow) {
childWindow.Close(); // Close the pyramid we created because disposable views are not restore later
m_dst.Window = m_src.Window;
}
AfterOpening();
}
internal bool IsPlaceholderVisible() {
if(!(m_dst.Window is PlaceholderWindow))
return false;
var pyramid = new ViewPyramid(m_dst.Window);
if(!pyramid.View || !pyramid.View.IsOfType(Types.HostView))
return false;
var actualView = pyramid.View.GetPropertyValue<View>("actualView");
return actualView == m_dst.Window;
}
public override void Close() {
var shouldRefocus = IsFocused() && IsPlaceholderVisible();
if(m_src.Window && m_dst.Window)
SwapWindows(m_src.Window, m_dst.Window); // Swap back the source window
base.Close();
if(shouldRefocus && m_src.Window)
m_src.Window.Focus();
}
}
}