using System; using System.Linq; using System.Runtime.CompilerServices; using UnityEditor; using UnityEngine; [assembly: InternalsVisibleToAttribute("FullscreenTests")] namespace FullscreenEditor { /// Main entry point for finding, creating and closing . public static class Fullscreen { private static FullscreenContainer[] cachedFullscreen; private static FullscreenContainer[] cachedFullscreenAll; [InitializeOnLoadMethod] private static void InitCache() { GetAllFullscreen(false, true); FullscreenCallbacks.beforeFullscreenOpen += (f) => GetAllFullscreen(false, true); FullscreenCallbacks.afterFullscreenOpen += (f) => GetAllFullscreen(false, true); FullscreenCallbacks.beforeFullscreenClose += (f) => GetAllFullscreen(false, true); FullscreenCallbacks.afterFullscreenClose += (f) => GetAllFullscreen(false, true); } /// Return all instances. /// Allow returning cached content. /// Do not return fullscreen containers that don't have a valid ContainerWindow. public static FullscreenContainer[] GetAllFullscreen(bool cached = true, bool ignoreUnknownState = true) { if(cached && cachedFullscreen != null && cachedFullscreenAll != null) return ignoreUnknownState ? cachedFullscreen : cachedFullscreenAll; cachedFullscreenAll = Resources.FindObjectsOfTypeAll(); if(!ignoreUnknownState) return cachedFullscreenAll; cachedFullscreen = cachedFullscreenAll .Where(fs => fs.m_dst.Container != null) .ToArray(); return cachedFullscreen; } /// Get the on the given point, or null if there is none. public static FullscreenContainer GetFullscreenOnPoint(Vector2 point) { return GetAllFullscreen() .FirstOrDefault(fullscreen => fullscreen.Rect.Contains(point)); } /// Get the that overlaps the given rect, or null if there is none. public static FullscreenContainer GetFullscreenOnRect(Rect rect) { return GetAllFullscreen() .FirstOrDefault(fullscreen => fullscreen.Rect.Overlaps(rect)); } /// Returns the parent for a given view or window, or null if it's not in fullscreen. /// Compare by the root view, otherwise compare by the container. public static FullscreenContainer GetFullscreenFromView(ScriptableObject viewOrWindow, bool rootView = true) { if(!viewOrWindow) return null; var pyramid = new ViewPyramid(viewOrWindow); return Fullscreen .GetAllFullscreen() .FirstOrDefault(fullscreen => rootView ? fullscreen.ActualViewPyramid.View == pyramid.View : fullscreen.ActualViewPyramid.Container == pyramid.Container ); } /// Create a for a given window. /// The window that will go fullscreen. If null a new one will be instantiated based on the given type. /// The type of the window to instantiate if the given window is null. /// Returns the newly created . public static FullscreenWindow MakeFullscreen(T window = null) where T : EditorWindow { return MakeFullscreen(typeof(T), window); } /// Create a for a given window. /// The type of the window to instantiate if the given window is null. /// The window that will go fullscreen. If null a new one will be instantiated based on the given type. /// Set this to true when the target window was created solely for fullscreen, /// this will cause it to be destroyed once the fullscreen closes, it has no effects if the target window is null. /// Returns the newly created . public static FullscreenWindow MakeFullscreen(Type type, EditorWindow window = null, bool disposableWindow = false) { var rect = FullscreenRects.GetFullscreenRect(FullscreenPreferences.RectSource, window); var fullscreen = ScriptableObject.CreateInstance(); fullscreen.OpenWindow(rect, type, window, disposableWindow); return fullscreen; } /// Create a for a given view. /// The view that will go fullscreen, cannot be null. /// Returns the newly created . public static FullscreenView MakeFullscreen(ScriptableObject view) { if(!view) throw new ArgumentNullException("view"); view.EnsureOfType(Types.View); var rect = FullscreenRects.GetFullscreenRect(FullscreenPreferences.RectSource, view); var fullscreen = ScriptableObject.CreateInstance(); fullscreen.OpenView(rect, view); return fullscreen; } /// Open a new fullscreen if there's none open, otherwise, close the one already open. /// The window that will go fullscreen. If null a new one will be instantiated based on the given type. /// The type of the window to instantiate if the given window is null. public static void ToggleFullscreen(T window = null) where T : EditorWindow { ToggleFullscreen(typeof(T), window); } /// Open a new fullscreen if there's none open, otherwise, close the one already open. /// The window that will go fullscreen. If null a new one will be instantiated based on the given type. /// The type of the window to instantiate if the given window is null. public static void ToggleFullscreen(Type type, EditorWindow window = null) { var rect = FullscreenRects.GetFullscreenRect(FullscreenPreferences.RectSource, window); var oldFullscreen = GetFullscreenFromView(window); if(oldFullscreen) { oldFullscreen.Close(); return; } oldFullscreen = GetFullscreenOnRect(rect); var newFullscreen = MakeFullscreen(type, window); newFullscreen.didPresent += () => { if(oldFullscreen) oldFullscreen.Close(); }; } /// Open a new fullscreen if there's none open, otherwise, close the one already open. /// The view that will go fullscreen, cannot be null. public static void ToggleFullscreen(ScriptableObject view) { var rect = FullscreenRects.GetFullscreenRect(FullscreenPreferences.RectSource, view); var oldFullscreen = GetFullscreenFromView(view); if(oldFullscreen) { oldFullscreen.Close(); return; } oldFullscreen = GetFullscreenOnRect(rect); var newFullscreen = MakeFullscreen(view); newFullscreen.didPresent += () => { if(oldFullscreen) oldFullscreen.Close(); }; } } }