internal static void BeginContainerGUI(GUILayoutUtility.LayoutCache cache, Event evt, IMGUIContainer container) { if (container.useOwnerObjectGUIState) { GUIUtility.BeginContainerFromOwner(container.elementPanel.ownerObject); } else { GUIUtility.BeginContainer(container.guiState); } s_ContainerStack.Push(container); GUIUtility.s_SkinMode = (int)container.contextType; GUIUtility.s_OriginalID = container.elementPanel.ownerObject.GetInstanceID(); if (Event.current == null) { Event.current = evt; } else { Event.current.CopyFrom(evt); } // call AFTER setting current event if (s_BeginContainerCallback != null) { s_BeginContainerCallback(container); } GUI.enabled = container.enabledInHierarchy; GUILayoutUtility.BeginContainer(cache); GUIUtility.ResetGlobalState(); }
internal static void BeginContainerGUI(GUILayoutUtility.LayoutCache cache, Event evt, IMGUIContainer container) { bool useOwnerObjectGUIState = container.useOwnerObjectGUIState; if (useOwnerObjectGUIState) { GUIUtility.BeginContainerFromOwner(container.elementPanel.ownerObject); } else { GUIUtility.BeginContainer(container.guiState); } UIElementsUtility.s_ContainerStack.Push(container); GUIUtility.s_SkinMode = (int)container.contextType; GUIUtility.s_OriginalID = container.elementPanel.ownerObject.GetInstanceID(); bool flag = Event.current == null; if (flag) { Event.current = evt; } else { Event.current.CopyFrom(evt); } bool flag2 = UIElementsUtility.s_BeginContainerCallback != null; if (flag2) { UIElementsUtility.s_BeginContainerCallback(container); } GUI.enabled = container.enabledInHierarchy; GUILayoutUtility.BeginContainer(cache); GUIUtility.ResetGlobalState(); }
internal static void BeginContainerGUI(GUILayoutUtility.LayoutCache cache, Event evt, IMGUIContainer container) { if (container.useOwnerObjectGUIState) { GUIUtility.BeginContainerFromOwner(container.elementPanel.ownerObject); } else { GUIUtility.BeginContainer(container.guiState); } UIElementsUtility.s_ContainerStack.Push(container); GUIUtility.s_SkinMode = (int)container.contextType; GUIUtility.s_OriginalID = container.elementPanel.ownerObject.GetInstanceID(); Event.current = evt; GUI.enabled = container.enabledInHierarchy; GUILayoutUtility.BeginContainer(cache); GUIUtility.ResetGlobalState(); Rect clipRect = container.lastWorldClip; if (clipRect.width == 0f || clipRect.height == 0f) { clipRect = container.worldBound; } Matrix4x4 lhs = container.worldTransform; if (evt.type == EventType.Repaint && container.elementPanel != null && container.elementPanel.stylePainter != null) { lhs = container.elementPanel.stylePainter.currentTransform; } GUIClip.SetTransform(lhs * Matrix4x4.Translate(container.layout.position), clipRect); }
internal static void BeginContainerGUI(GUILayoutUtility.LayoutCache cache, int instanceID, Event evt, IMGUIContainer container) { GUIUtility.BeginContainer(instanceID); UIElementsUtility.s_ContainerStack.Push(container); GUIUtility.s_SkinMode = (int)container.contextType; GUIUtility.s_OriginalID = instanceID; Event.current = evt; if (UIElementsUtility.s_BeginContainerCallback != null) { UIElementsUtility.s_BeginContainerCallback(container); } GUILayoutUtility.BeginContainer(cache); GUIUtility.ResetGlobalState(); Rect clipRect = container.lastWorldClip; if (clipRect.width == 0f || clipRect.height == 0f) { clipRect = container.globalBound; } Matrix4x4 rhs = Matrix4x4.TRS(new Vector3(container.position.x, container.position.y, 0f), Quaternion.identity, Vector3.one); GUIClip.SetTransform(container.globalTransform * rhs, clipRect); }
private VisualElement CreateIMGUIInspectorFromEditor(SerializedObject serializedObject, Editor editor, bool reuseIMGUIContainer) { if ((mode & (Mode.IMGUICustom | Mode.IMGUIDefault)) == 0) { return(null); } if ((mode & Mode.IMGUICustom) > 0 && (mode & Mode.IMGUIDefault) == 0 && editor is GenericInspector) { return(null); } if ((mode & Mode.IMGUICustom) == 0 && (mode & Mode.IMGUIDefault) > 0 && !(editor is GenericInspector)) { editor = ScriptableObject.CreateInstance <GenericInspector>(); editor.hideFlags = HideFlags.HideAndDontSave; editor.InternalSetTargets(new[] { serializedObject.targetObject }); } if (editor is GenericInspector) { AddToClassList(iMGUIDefaultVariantUssClassName); if ((mode & Mode.DebugMod) > 0) { AddToClassList(debugVariantUssClassName); editor.inspectorMode = InspectorMode.Debug; } else if ((mode & Mode.DebugInternalMod) > 0) { AddToClassList(debugInternalVariantUssClassName); editor.inspectorMode = InspectorMode.DebugInternal; } } else { AddToClassList(iMGUICustomVariantUssClassName); } IMGUIContainer inspector; // Reusing the existing IMGUIContainer allows us to re-use the existing gui state, when we are drawing the same inspector this will let us keep the same control ids if (reuseIMGUIContainer && m_IMGUIContainer != null) { inspector = m_IMGUIContainer; } else { inspector = new IMGUIContainer(); } m_IgnoreOnInspectorGUIErrors = false; inspector.onGUIHandler = () => { // It's possible to run 2-3 frames after the tracker of this inspector window has // been recreated, and with it the Editor and its SerializedObject. One example of // when this happens is when the Preview window is detached from a *second* instance // of an InspectorWindow and re-attached. // // This is only a problem for the *second* (or third, forth, etc) instance of // the InspectorWindow because only the first instance can use the // ActiveEditorTracker.sharedTracker in InspectorWindow.CreateTracker(). The // other instances have to create a new tracker...each time. // // Not an ideal solution, but basically we temporarily hold the printing to console // for errors for which GUIUtility.ShouldRethrowException(e) returns false. // The errors that may occur during this brief "bad state" are SerializedProperty // errors. If the custom Editor created and remembered references to some // SerializedProperties during its OnEnable(), those references will be invalid // when the tracker is refreshed, until this GUIHandler is reassigned. This fix // just ignores those errors. // // We don't simply early return here because that can break some tests that // rely heavily on yields and timing of UI redraws. Yes.. // // case 1119612 if (editor.m_SerializedObject == null) { editor.Repaint(); m_IgnoreOnInspectorGUIErrors = true; } if ((editor.target == null && !GenericInspector.ObjectIsMonoBehaviourOrScriptableObject(editor.target)) || !editor.serializedObject.isValid) { return; } EditorGUIUtility.ResetGUIState(); using (new EditorGUI.DisabledScope(!editor.IsEnabled())) { var genericEditor = editor as GenericInspector; if (genericEditor != null) { switch (mode) { case Mode.Normal: genericEditor.inspectorMode = InspectorMode.Normal; break; case Mode.Default: genericEditor.inspectorMode = InspectorMode.Debug; break; case Mode.Custom: genericEditor.inspectorMode = InspectorMode.DebugInternal; break; case Mode.IMGUI: break; } } //set the current PropertyHandlerCache to the current editor ScriptAttributeUtility.propertyHandlerCache = editor.propertyHandlerCache; var originalHierarchyMode = EditorGUIUtility.hierarchyMode; EditorGUIUtility.hierarchyMode = true; var originalWideMode = SetWideModeForWidth(inspector); GUIStyle editorWrapper = (editor.UseDefaultMargins() ? EditorStyles.inspectorDefaultMargins : GUIStyle.none); try { GUI.changed = false; using (new InspectorWindowUtils.LayoutGroupChecker()) { EditorGUILayout.BeginVertical(editorWrapper); { // we have no guarantees regarding what happens in the try/catch block below, // so we need to save state here and restore it afterwards, // the natural thing to do would be using SavedGUIState, // but it implicitly resets keyboards bindings and it breaks functionality. // We have identified issues with layout so we just save that for the time being. var layoutCache = new GUILayoutUtility.LayoutCache(GUILayoutUtility.current); try { var rebuildOptimizedGUIBlocks = GetRebuildOptimizedGUIBlocks(editor.target); rebuildOptimizedGUIBlocks |= editor.isInspectorDirty; float height; if (editor.GetOptimizedGUIBlock(rebuildOptimizedGUIBlocks, visible, out height)) { var contentRect = GUILayoutUtility.GetRect(0, visible ? height : 0); // Layout events are ignored in the optimized code path // The exception is when we are drawing a GenericInspector, they always use the optimized path and must therefore run at least one layout calculation in it if (Event.current.type == EventType.Layout && !(editor is GenericInspector)) { return; } InspectorWindowUtils.DrawAddedComponentBackground(contentRect, editor.targets); // Draw content if (visible) { GUI.changed = false; editor.OnOptimizedInspectorGUI(contentRect); } } else { InspectorWindowUtils.DrawAddedComponentBackground(contentRect, editor.targets); editor.OnInspectorGUI(); } } catch (Exception e) { if (GUIUtility.ShouldRethrowException(e)) { throw; } if (!m_IgnoreOnInspectorGUIErrors) { Debug.LogException(e); } } finally { GUILayoutUtility.current = layoutCache; } } EditorGUILayout.EndVertical(); } } finally { if (GUI.changed) { // This forces a relayout of all imguicontainers in this inspector window. // fixes part of case 1148706 var element = inspector.GetFirstAncestorOfType <EditorElement>(); if (element != null) { EditorElement.InvalidateIMGUILayouts(element.parent); } } EditorGUIUtility.wideMode = originalWideMode; EditorGUIUtility.hierarchyMode = originalHierarchyMode; } } }; inspector.style.overflow = Overflow.Visible; m_IMGUIContainer = inspector; if (!(editor is GenericInspector)) { inspector.AddToClassList(customInspectorUssClassName); } inspector.AddToClassList(iMGUIContainerUssClassName); AddToClassList(iMGUIInspectorVariantUssClassName); return(inspector); }