| using UnityEngine; | 
| using UnityEngine.PostProcessing; | 
| using System; | 
| using System.Collections.Generic; | 
| using System.Linq; | 
| using System.Reflection; | 
|   | 
| namespace UnityEditor.PostProcessing | 
| { | 
|     //[CanEditMultipleObjects] | 
|     [CustomEditor(typeof(PostProcessingProfile))] | 
|     public class PostProcessingInspector : Editor | 
|     { | 
|         static GUIContent s_PreviewTitle = new GUIContent("Monitors"); | 
|   | 
|         PostProcessingProfile m_ConcreteTarget | 
|         { | 
|             get { return target as PostProcessingProfile; } | 
|         } | 
|   | 
|         int m_CurrentMonitorID | 
|         { | 
|             get { return m_ConcreteTarget.monitors.currentMonitorID; } | 
|             set { m_ConcreteTarget.monitors.currentMonitorID = value; } | 
|         } | 
|   | 
|         List<PostProcessingMonitor> m_Monitors; | 
|         GUIContent[] m_MonitorNames; | 
|         Dictionary<PostProcessingModelEditor, PostProcessingModel> m_CustomEditors = new Dictionary<PostProcessingModelEditor, PostProcessingModel>(); | 
|   | 
|         public bool IsInteractivePreviewOpened { get; private set; } | 
|   | 
|         void OnEnable() | 
|         { | 
|             if (target == null) | 
|                 return; | 
|   | 
|             // Aggregate custom post-fx editors | 
|             var assembly = Assembly.GetAssembly(typeof(PostProcessingInspector)); | 
|   | 
|             var editorTypes = assembly.GetTypes() | 
|                 .Where(x => x.IsDefined(typeof(PostProcessingModelEditorAttribute), false)); | 
|   | 
|             var customEditors = new Dictionary<Type, PostProcessingModelEditor>(); | 
|             foreach (var editor in editorTypes) | 
|             { | 
|                 var attr = (PostProcessingModelEditorAttribute)editor.GetCustomAttributes(typeof(PostProcessingModelEditorAttribute), false)[0]; | 
|                 var effectType = attr.type; | 
|                 var alwaysEnabled = attr.alwaysEnabled; | 
|   | 
|                 var editorInst = (PostProcessingModelEditor)Activator.CreateInstance(editor); | 
|                 editorInst.alwaysEnabled = alwaysEnabled; | 
|                 editorInst.profile = target as PostProcessingProfile; | 
|                 editorInst.inspector = this; | 
|                 customEditors.Add(effectType, editorInst); | 
|             } | 
|   | 
|             // ... and corresponding models | 
|             var baseType = target.GetType(); | 
|             var property = serializedObject.GetIterator(); | 
|   | 
|             while (property.Next(true)) | 
|             { | 
|                 if (!property.hasChildren) | 
|                     continue; | 
|   | 
|                 var type = baseType; | 
|                 var srcObject = ReflectionUtils.GetFieldValueFromPath(serializedObject.targetObject, ref type, property.propertyPath); | 
|   | 
|                 if (srcObject == null) | 
|                     continue; | 
|   | 
|                 PostProcessingModelEditor editor; | 
|                 if (customEditors.TryGetValue(type, out editor)) | 
|                 { | 
|                     var effect = (PostProcessingModel)srcObject; | 
|   | 
|                     if (editor.alwaysEnabled) | 
|                         effect.enabled = editor.alwaysEnabled; | 
|   | 
|                     m_CustomEditors.Add(editor, effect); | 
|                     editor.target = effect; | 
|                     editor.serializedProperty = property.Copy(); | 
|                     editor.OnPreEnable(); | 
|                 } | 
|             } | 
|   | 
|             // Prepare monitors | 
|             m_Monitors = new List<PostProcessingMonitor>(); | 
|   | 
|             var monitors = new List<PostProcessingMonitor> | 
|             { | 
|                 new HistogramMonitor(), | 
|                 new WaveformMonitor(), | 
|                 new ParadeMonitor(), | 
|                 new VectorscopeMonitor() | 
|             }; | 
|   | 
|             var monitorNames = new List<GUIContent>(); | 
|   | 
|             foreach (var monitor in monitors) | 
|             { | 
|                 if (monitor.IsSupported()) | 
|                 { | 
|                     monitor.Init(m_ConcreteTarget.monitors, this); | 
|                     m_Monitors.Add(monitor); | 
|                     monitorNames.Add(monitor.GetMonitorTitle()); | 
|                 } | 
|             } | 
|   | 
|             m_MonitorNames = monitorNames.ToArray(); | 
|   | 
|             if (m_Monitors.Count > 0) | 
|                 m_ConcreteTarget.monitors.onFrameEndEditorOnly = OnFrameEnd; | 
|         } | 
|   | 
|         void OnDisable() | 
|         { | 
|             if (m_CustomEditors != null) | 
|             { | 
|                 foreach (var editor in m_CustomEditors.Keys) | 
|                     editor.OnDisable(); | 
|   | 
|                 m_CustomEditors.Clear(); | 
|             } | 
|   | 
|             if (m_Monitors != null) | 
|             { | 
|                 foreach (var monitor in m_Monitors) | 
|                     monitor.Dispose(); | 
|   | 
|                 m_Monitors.Clear(); | 
|             } | 
|   | 
|             if (m_ConcreteTarget != null) | 
|                 m_ConcreteTarget.monitors.onFrameEndEditorOnly = null; | 
|         } | 
|   | 
|         void OnFrameEnd(RenderTexture source) | 
|         { | 
|             if (!IsInteractivePreviewOpened) | 
|                 return; | 
|   | 
|             if (m_CurrentMonitorID < m_Monitors.Count) | 
|                 m_Monitors[m_CurrentMonitorID].OnFrameData(source); | 
|   | 
|             IsInteractivePreviewOpened = false; | 
|         } | 
|   | 
|         public override void OnInspectorGUI() | 
|         { | 
|             serializedObject.Update(); | 
|   | 
|             // Handles undo/redo events first (before they get used by the editors' widgets) | 
|             var e = Event.current; | 
|             if (e.type == EventType.ValidateCommand && e.commandName == "UndoRedoPerformed") | 
|             { | 
|                 foreach (var editor in m_CustomEditors) | 
|                     editor.Value.OnValidate(); | 
|             } | 
|   | 
|             if (!m_ConcreteTarget.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.None)) | 
|                 EditorGUILayout.HelpBox("A debug view is currently enabled. Changes done to an effect might not be visible.", MessageType.Info); | 
|   | 
|             foreach (var editor in m_CustomEditors) | 
|             { | 
|                 EditorGUI.BeginChangeCheck(); | 
|   | 
|                 editor.Key.OnGUI(); | 
|   | 
|                 if (EditorGUI.EndChangeCheck()) | 
|                     editor.Value.OnValidate(); | 
|             } | 
|   | 
|             serializedObject.ApplyModifiedProperties(); | 
|         } | 
|   | 
|         public override GUIContent GetPreviewTitle() | 
|         { | 
|             return s_PreviewTitle; | 
|         } | 
|   | 
|         public override bool HasPreviewGUI() | 
|         { | 
|             return GraphicsUtils.supportsDX11 && m_Monitors.Count > 0; | 
|         } | 
|   | 
|         public override void OnPreviewSettings() | 
|         { | 
|             using (new EditorGUILayout.HorizontalScope()) | 
|             { | 
|                 if (m_CurrentMonitorID < m_Monitors.Count) | 
|                     m_Monitors[m_CurrentMonitorID].OnMonitorSettings(); | 
|   | 
|                 GUILayout.Space(5); | 
|                 m_CurrentMonitorID = EditorGUILayout.Popup(m_CurrentMonitorID, m_MonitorNames, FxStyles.preDropdown, GUILayout.MaxWidth(100f)); | 
|             } | 
|         } | 
|   | 
|         public override void OnInteractivePreviewGUI(Rect r, GUIStyle background) | 
|         { | 
|             IsInteractivePreviewOpened = true; | 
|   | 
|             if (m_CurrentMonitorID < m_Monitors.Count) | 
|                 m_Monitors[m_CurrentMonitorID].OnMonitorGUI(r); | 
|         } | 
|     } | 
| } |