using System; using UnityEngine; using UnityEngine.UIElements; namespace Phantom.XRMOD.UnityFusion.Editor { /// /// Class that can wrap the /// of a component header and allow injecting /// drawing logic to occur before and after its drawing. /// internal class ComponentHeaderWrapper { private readonly IMGUIContainer headerElement; private readonly Component component; private readonly Action wrappedOnGUIHandler; private readonly bool supportsRichText; private ComponentHeaderWrapper(IMGUIContainer headerElement, Component component, bool supportsRichText) { this.headerElement = headerElement; this.component = component; this.supportsRichText = supportsRichText; wrappedOnGUIHandler = headerElement.onGUIHandler; } public static void WrapIfNotAlreadyWrapped((UnityEditor.Editor editor, IMGUIContainer header) editorAndHeader, bool supportsRichText) { var header = editorAndHeader.header; var onGUIHandler = header.onGUIHandler; if(string.Equals(onGUIHandler.Method.Name, nameof(DrawWrappedHeaderGUI))) { return; } var targetComponent = editorAndHeader.editor.target as Component; var wrapper = new ComponentHeaderWrapper(header, targetComponent, supportsRichText); header.onGUIHandler = wrapper.DrawWrappedHeaderGUI; } private void DrawWrappedHeaderGUI() { if(!component) { Unwrap(); return; } var headerRect = headerElement.contentRect; bool headerIsSelected = headerElement.focusController.focusedElement == headerElement; ComponentHeader.InvokeBeforeHeaderGUI(component, headerRect, headerIsSelected, supportsRichText); wrappedOnGUIHandler?.Invoke(); ComponentHeader.InvokeAfterHeaderGUI(component, headerRect, headerIsSelected, supportsRichText); } private void Unwrap() { if(headerElement is not null) { headerElement.onGUIHandler = wrappedOnGUIHandler; } } } }