using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityObject = UnityEngine.Object;
using HostView = UnityEngine.ScriptableObject;
using View = UnityEngine.ScriptableObject;
using ContainerWindow = UnityEngine.ScriptableObject;
namespace FullscreenEditor {
/// Manages the WindowContainers, Views and Windows that will be fullscreened.
public abstract partial class FullscreenContainer : ScriptableObject {
/// The m_src will have all it's fields null if we've instantiated the window by ourselves.
/// Window - The window to fullscreen, null if we're opening a view.
/// View - The view to fullscreen, or window.m_Parent if we're opening a window.
/// Container - The source container, from the source view.
///
[SerializeField] public ViewPyramid m_src;
///
/// Window - The placeholder window or a window created specially for this fullscreen.
/// View - HostView created for this fullscreen.
/// Container - The container that will be used for fullscreen, with its mode set to "Popup".
///
[SerializeField] public ViewPyramid m_dst;
/// Create a ContainerWindow and HostView, then asigns a window to them and shows it as a popup.
/// The initial position of the ContainerWindow, can be changed later using the property.
/// The initial window for the newly created ContainerWindow and HostView.
/// Returns the pyramid of views we've created.
protected ViewPyramid CreateFullscreenViewPyramid(Rect rect, EditorWindow childWindow) {
var hv = CreateInstance(Types.HostView);
var cw = CreateInstance(Types.ContainerWindow);
hv.name = name;
cw.name = name;
childWindow.name = name;
hv.SetPropertyValue("actualView", childWindow);
// Order is important here: first set rect of container, then assign main view, then apply various settings, then show.
// Otherwise the rect won't be set until first resize happens.
cw.SetPropertyValue("position", rect);
cw.SetPropertyValue("rootView", hv);
childWindow.InvokeMethod("MakeParentsSettingsMatchMe");
var loadPosition = false;
var displayImmediately = true;
var setFocus = true;
if (cw.HasMethod("Show", new[] { typeof(int), typeof(bool), typeof(bool), typeof(bool), typeof(int) }))
cw.InvokeMethod("Show", (int)ShowMode.NoShadow, loadPosition, displayImmediately, setFocus, 0);
else if (cw.HasMethod("Show", new[] { typeof(int), typeof(bool), typeof(bool) }))
cw.InvokeMethod("Show", (int)ShowMode.NoShadow, loadPosition, displayImmediately);
else
cw.InvokeMethod("Show", (int)ShowMode.NoShadow, loadPosition, displayImmediately, setFocus);
// set min/max size now that native window is not null so that it will e.g., use proper styleMask on macOS
cw.InvokeMethod("SetMinMaxSizes", rect.size, rect.size); // min, max
cw.SetFieldValue("m_ShowMode", (int)ShowMode.PopupMenu); // Prevents window decoration from being draw
cw.SetFieldValue("m_DontSaveToLayout", true);
Logger.Debug(this, "Created {0}, resolution {1:0}x{2:0}, pos {3:0}", name, rect.width, rect.height, rect.min);
return new ViewPyramid() { Window = childWindow, View = hv, Container = cw };
}
/// Prevents any repaint on the container window. This fixes some glitches on macOS.
/// The ContainerWindow to freeze the repaints.
/// Wheter to freeze or unfreeze the container.
protected void SetFreezeContainer(ContainerWindow containerWindow, bool freeze) {
containerWindow.InvokeMethod("SetFreezeDisplay", freeze);
}
/// Method that will be called just before creating the ContainerWindow for this fullscreen.
protected virtual void BeforeOpening() {
FullscreenCallbacks.beforeFullscreenOpen(this);
if (m_dst.Container)
new Exception("Container already has a fullscreened view");
}
/// Method that will be called after the creation of the ContainerWindow for this fullscreen.
protected virtual void AfterOpening() {
After.Frames(2, () => {
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
didPresent.Invoke();
didPresent = null;
});
Logger.Debug(this, "{6}\n\nSRC\nWindow: {0}\nView: {1}\nContainer: {2}\n\nDST\nWindow: {3}\nView: {4}\nContainer: {5}\n",
m_src.Window,
m_src.View,
m_src.Container,
m_dst.Window,
m_dst.View,
m_dst.Container,
name
);
FullscreenCallbacks.afterFullscreenOpen(this);
}
}
}