You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
7.6 KiB

  1. using System;
  2. using UnityEngine;
  3. using System.Collections.Generic;
  4. using System.Globalization;
  5. using System.Reflection;
  6. using UnityEngine.PostProcessing;
  7. namespace UnityEditor.PostProcessing
  8. {
  9. public static class EditorGUIHelper
  10. {
  11. static EditorGUIHelper()
  12. {
  13. s_GUIContentCache = new Dictionary<string, GUIContent>();
  14. }
  15. #region GUIContent caching
  16. static Dictionary<string, GUIContent> s_GUIContentCache;
  17. public static GUIContent GetContent(string textAndTooltip)
  18. {
  19. if (string.IsNullOrEmpty(textAndTooltip))
  20. return GUIContent.none;
  21. GUIContent content;
  22. if (!s_GUIContentCache.TryGetValue(textAndTooltip, out content))
  23. {
  24. var s = textAndTooltip.Split('|');
  25. content = new GUIContent(s[0]);
  26. if (s.Length > 1 && !string.IsNullOrEmpty(s[1]))
  27. content.tooltip = s[1];
  28. s_GUIContentCache.Add(textAndTooltip, content);
  29. }
  30. return content;
  31. }
  32. #endregion
  33. public static bool Header(string title, SerializedProperty group, Action resetAction)
  34. {
  35. var rect = GUILayoutUtility.GetRect(16f, 22f, FxStyles.header);
  36. GUI.Box(rect, title, FxStyles.header);
  37. var display = group == null || group.isExpanded;
  38. var foldoutRect = new Rect(rect.x + 4f, rect.y + 2f, 13f, 13f);
  39. var e = Event.current;
  40. var popupRect = new Rect(rect.x + rect.width - FxStyles.paneOptionsIcon.width - 5f, rect.y + FxStyles.paneOptionsIcon.height / 2f + 1f, FxStyles.paneOptionsIcon.width, FxStyles.paneOptionsIcon.height);
  41. GUI.DrawTexture(popupRect, FxStyles.paneOptionsIcon);
  42. if (e.type == EventType.Repaint)
  43. FxStyles.headerFoldout.Draw(foldoutRect, false, false, display, false);
  44. if (e.type == EventType.MouseDown)
  45. {
  46. if (popupRect.Contains(e.mousePosition))
  47. {
  48. var popup = new GenericMenu();
  49. popup.AddItem(GetContent("Reset"), false, () => resetAction());
  50. popup.AddSeparator(string.Empty);
  51. popup.AddItem(GetContent("Copy Settings"), false, () => CopySettings(group));
  52. if (CanPaste(group))
  53. popup.AddItem(GetContent("Paste Settings"), false, () => PasteSettings(group));
  54. else
  55. popup.AddDisabledItem(GetContent("Paste Settings"));
  56. popup.ShowAsContext();
  57. }
  58. else if (rect.Contains(e.mousePosition) && group != null)
  59. {
  60. display = !display;
  61. if (group != null)
  62. group.isExpanded = !group.isExpanded;
  63. e.Use();
  64. }
  65. }
  66. return display;
  67. }
  68. public static bool Header(string title, SerializedProperty group, SerializedProperty enabledField, Action resetAction)
  69. {
  70. var field = ReflectionUtils.GetFieldInfoFromPath(enabledField.serializedObject.targetObject, enabledField.propertyPath);
  71. object parent = null;
  72. PropertyInfo prop = null;
  73. if (field != null && field.IsDefined(typeof(GetSetAttribute), false))
  74. {
  75. var attr = (GetSetAttribute)field.GetCustomAttributes(typeof(GetSetAttribute), false)[0];
  76. parent = ReflectionUtils.GetParentObject(enabledField.propertyPath, enabledField.serializedObject.targetObject);
  77. prop = parent.GetType().GetProperty(attr.name);
  78. }
  79. var display = group == null || group.isExpanded;
  80. var enabled = enabledField.boolValue;
  81. var rect = GUILayoutUtility.GetRect(16f, 22f, FxStyles.header);
  82. GUI.Box(rect, title, FxStyles.header);
  83. var toggleRect = new Rect(rect.x + 4f, rect.y + 4f, 13f, 13f);
  84. var e = Event.current;
  85. var popupRect = new Rect(rect.x + rect.width - FxStyles.paneOptionsIcon.width - 5f, rect.y + FxStyles.paneOptionsIcon.height / 2f + 1f, FxStyles.paneOptionsIcon.width, FxStyles.paneOptionsIcon.height);
  86. GUI.DrawTexture(popupRect, FxStyles.paneOptionsIcon);
  87. if (e.type == EventType.Repaint)
  88. FxStyles.headerCheckbox.Draw(toggleRect, false, false, enabled, false);
  89. if (e.type == EventType.MouseDown)
  90. {
  91. const float kOffset = 2f;
  92. toggleRect.x -= kOffset;
  93. toggleRect.y -= kOffset;
  94. toggleRect.width += kOffset * 2f;
  95. toggleRect.height += kOffset * 2f;
  96. if (toggleRect.Contains(e.mousePosition))
  97. {
  98. enabledField.boolValue = !enabledField.boolValue;
  99. if (prop != null)
  100. prop.SetValue(parent, enabledField.boolValue, null);
  101. e.Use();
  102. }
  103. else if (popupRect.Contains(e.mousePosition))
  104. {
  105. var popup = new GenericMenu();
  106. popup.AddItem(GetContent("Reset"), false, () => resetAction());
  107. popup.AddSeparator(string.Empty);
  108. popup.AddItem(GetContent("Copy Settings"), false, () => CopySettings(group));
  109. if (CanPaste(group))
  110. popup.AddItem(GetContent("Paste Settings"), false, () => PasteSettings(group));
  111. else
  112. popup.AddDisabledItem(GetContent("Paste Settings"));
  113. popup.ShowAsContext();
  114. }
  115. else if (rect.Contains(e.mousePosition) && group != null)
  116. {
  117. display = !display;
  118. group.isExpanded = !group.isExpanded;
  119. e.Use();
  120. }
  121. }
  122. return display;
  123. }
  124. static void CopySettings(SerializedProperty settings)
  125. {
  126. var t = typeof(PostProcessingProfile);
  127. var settingsStruct = ReflectionUtils.GetFieldValueFromPath(settings.serializedObject.targetObject, ref t, settings.propertyPath);
  128. var serializedString = t.ToString() + '|' + JsonUtility.ToJson(settingsStruct);
  129. EditorGUIUtility.systemCopyBuffer = serializedString;
  130. }
  131. static bool CanPaste(SerializedProperty settings)
  132. {
  133. var data = EditorGUIUtility.systemCopyBuffer;
  134. if (string.IsNullOrEmpty(data))
  135. return false;
  136. var parts = data.Split('|');
  137. if (string.IsNullOrEmpty(parts[0]))
  138. return false;
  139. var field = ReflectionUtils.GetFieldInfoFromPath(settings.serializedObject.targetObject, settings.propertyPath);
  140. return parts[0] == field.FieldType.ToString();
  141. }
  142. static void PasteSettings(SerializedProperty settings)
  143. {
  144. Undo.RecordObject(settings.serializedObject.targetObject, "Paste effect settings");
  145. var field = ReflectionUtils.GetFieldInfoFromPath(settings.serializedObject.targetObject, settings.propertyPath);
  146. var json = EditorGUIUtility.systemCopyBuffer.Substring(field.FieldType.ToString().Length + 1);
  147. var obj = JsonUtility.FromJson(json, field.FieldType);
  148. var parent = ReflectionUtils.GetParentObject(settings.propertyPath, settings.serializedObject.targetObject);
  149. field.SetValue(parent, obj, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CultureInfo.CurrentCulture);
  150. }
  151. }
  152. }