VolumeComponentProvider.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Rendering;
  5. namespace UnityEditor.Rendering
  6. {
  7. using IProvider = FilterWindow.IProvider;
  8. using Element = FilterWindow.Element;
  9. using GroupElement = FilterWindow.GroupElement;
  10. class VolumeComponentProvider : IProvider
  11. {
  12. class VolumeComponentElement : Element
  13. {
  14. public Type type;
  15. public VolumeComponentElement(int level, string label, Type type)
  16. {
  17. this.level = level;
  18. this.type = type;
  19. // TODO: Add support for custom icons
  20. content = new GUIContent(label);
  21. }
  22. }
  23. class PathNode : IComparable<PathNode>
  24. {
  25. public List<PathNode> nodes = new List<PathNode>();
  26. public string name;
  27. public Type type;
  28. public int CompareTo(PathNode other)
  29. {
  30. return name.CompareTo(other.name);
  31. }
  32. }
  33. public Vector2 position { get; set; }
  34. VolumeProfile m_Target;
  35. VolumeComponentListEditor m_TargetEditor;
  36. public VolumeComponentProvider(VolumeProfile target, VolumeComponentListEditor targetEditor)
  37. {
  38. m_Target = target;
  39. m_TargetEditor = targetEditor;
  40. }
  41. public void CreateComponentTree(List<Element> tree)
  42. {
  43. tree.Add(new GroupElement(0, "Volume Overrides"));
  44. var types = VolumeManager.instance.baseComponentTypeArray;
  45. var rootNode = new PathNode();
  46. foreach (var t in types)
  47. {
  48. // Skip components that have already been added to the volume
  49. if (m_Target.Has(t))
  50. continue;
  51. string path = string.Empty;
  52. // Look for a VolumeComponentMenu attribute
  53. var attrs = t.GetCustomAttributes(false);
  54. bool skipComponent = false;
  55. foreach (var attr in attrs)
  56. {
  57. var attrMenu = attr as VolumeComponentMenu;
  58. if (attrMenu != null)
  59. path = attrMenu.menu;
  60. var attrDeprecated = attr as VolumeComponentDeprecated;
  61. if (attrDeprecated != null)
  62. skipComponent = true;
  63. }
  64. if (skipComponent)
  65. continue;
  66. // If no attribute or in case something went wrong when grabbing it, fallback to a
  67. // beautified class name
  68. if (string.IsNullOrEmpty(path))
  69. path = ObjectNames.NicifyVariableName(t.Name);
  70. // Prep the categories & types tree
  71. AddNode(rootNode, path, t);
  72. }
  73. // Recursively add all elements to the tree
  74. Traverse(rootNode, 1, tree);
  75. }
  76. public bool GoToChild(Element element, bool addIfComponent)
  77. {
  78. if (element is VolumeComponentElement)
  79. {
  80. var e = (VolumeComponentElement)element;
  81. m_TargetEditor.AddComponent(e.type);
  82. return true;
  83. }
  84. return false;
  85. }
  86. void AddNode(PathNode root, string path, Type type)
  87. {
  88. var current = root;
  89. var parts = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
  90. foreach (var part in parts)
  91. {
  92. var child = current.nodes.Find(x => x.name == part);
  93. if (child == null)
  94. {
  95. child = new PathNode { name = part, type = type };
  96. current.nodes.Add(child);
  97. }
  98. current = child;
  99. }
  100. }
  101. void Traverse(PathNode node, int depth, List<Element> tree)
  102. {
  103. node.nodes.Sort();
  104. foreach (var n in node.nodes)
  105. {
  106. if (n.nodes.Count > 0) // Group
  107. {
  108. tree.Add(new GroupElement(depth, n.name));
  109. Traverse(n, depth + 1, tree);
  110. }
  111. else // Element
  112. {
  113. tree.Add(new VolumeComponentElement(depth, n.name, n.type));
  114. }
  115. }
  116. }
  117. }
  118. }