浏览代码

Move contextual actions from node search menu into actual context menu

/main
Peter Bay Bastian 7 年前
当前提交
72c4bdea
共有 4 个文件被更改,包括 116 次插入118 次删除
  1. 119
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/SearchWindowProvider.cs
  2. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs
  3. 80
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs
  4. 31
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs

119
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/SearchWindowProvider.cs


GraphView m_GraphView;
Texture2D m_Icon;
const string k_Actions = "Actions";
const string k_AddNode = "Add Node";
const string k_ConvertToProperty = "Convert To Property";
const string k_ConvertToInlineNode = "Convert To Inline Node";
const string k_ConvertToSubgraph = "Convert To Sub-graph";
const string k_CopyShader = "Copy Shader To Clipboard";
public Action onConvertToSubgraphClick { get; set; }
public void Initialize(EditorWindow editorWindow, AbstractMaterialGraph graph, GraphView graphView)
{
m_EditorWindow = editorWindow;

// First item in the tree is the title of the window.
var tree = new List<SearchTreeEntry>
{
new SearchTreeGroupEntry(new GUIContent(k_Actions), 0),
new SearchTreeGroupEntry(new GUIContent(k_AddNode)) { level = 1 },
new SearchTreeGroupEntry(new GUIContent("Create Node"), 0),
// Add in contextual node actions
var selection = m_GraphView.selection.OfType<MaterialNodeView>().Where(v => v.node != null).ToList();
if (selection.Any())
tree.Add(new SearchTreeEntry(new GUIContent(k_ConvertToSubgraph, m_Icon)) { level = 1 });
if (selection.Any(v => v.node is IPropertyFromNode))
tree.Add(new SearchTreeEntry(new GUIContent(k_ConvertToProperty, m_Icon)) { level = 1 });
if (selection.Any(v => v.node is PropertyNode))
tree.Add(new SearchTreeEntry(new GUIContent(k_ConvertToInlineNode, m_Icon)) { level = 1 });
if (selection.Count == 1 && selection.First().node.hasPreview)
tree.Add(new SearchTreeEntry(new GUIContent(k_CopyShader, m_Icon)) { level = 1 });
foreach (var nestedEntry in nestedEntries)
{

{
var group = nestedEntry.title[i];
groups.Add(group);
tree.Add(new SearchTreeGroupEntry(new GUIContent(group)) { level = i + 2 });
tree.Add(new SearchTreeGroupEntry(new GUIContent(group)) { level = i + 1 });
tree.Add(new SearchTreeEntry(new GUIContent(nestedEntry.title.Last(), m_Icon)) { level = nestedEntry.title.Length + 1, userData = nestedEntry.userData });
tree.Add(new SearchTreeEntry(new GUIContent(nestedEntry.title.Last(), m_Icon)) { level = nestedEntry.title.Length, userData = nestedEntry.userData });
}
return tree;

{
if (entry.name == k_ConvertToProperty)
return OnConvertToProperty();
if (entry.name == k_ConvertToInlineNode)
return OnConvertToInlineNode();
if (entry.name == k_ConvertToSubgraph)
return OnConvertToSubgraph();
if (entry.name == k_CopyShader)
return OnCopyShader();
return OnAddNode(entry, context);
}
bool OnCopyShader()
{
var copyFromNode = m_GraphView.selection.OfType<MaterialNodeView>().First().node;
List<PropertyCollector.TextureInfo> textureInfo;
var masterNode = copyFromNode as MasterNode;
if (masterNode != null)
{
var shader = masterNode.GetShader(GenerationMode.ForReals, masterNode.name, out textureInfo);
GUIUtility.systemCopyBuffer = shader;
}
else
{
PreviewMode previewMode;
FloatShaderProperty outputIdProperty;
var shader = m_Graph.GetShader(copyFromNode, GenerationMode.ForReals, copyFromNode.name, out textureInfo, out previewMode, out outputIdProperty);
GUIUtility.systemCopyBuffer = shader;
}
return true;
}
bool OnConvertToSubgraph()
{
if (onConvertToSubgraphClick != null) onConvertToSubgraphClick();
return true;
}
static List<IEdge> s_TempEdges = new List<IEdge>();
bool OnConvertToProperty()
{
if (m_GraphView == null)
return false;
var selectedNodeViews = m_GraphView.selection.OfType<MaterialNodeView>().Select(x => x.node).ToList();
foreach (var node in selectedNodeViews)
{
if (!(node is IPropertyFromNode))
continue;
var converter = node as IPropertyFromNode;
var prop = converter.AsShaderProperty();
m_Graph.AddShaderProperty(prop);
var propNode = new PropertyNode();
propNode.drawState = node.drawState;
m_Graph.AddNode(propNode);
propNode.propertyGuid = prop.guid;
var oldSlot = node.FindSlot<MaterialSlot>(converter.outputSlotId);
var newSlot = propNode.FindSlot<MaterialSlot>(PropertyNode.OutputSlotId);
s_TempEdges.Clear();
m_Graph.GetEdges(oldSlot.slotReference, s_TempEdges);
foreach (var edge in s_TempEdges)
m_Graph.Connect(newSlot.slotReference, edge.inputSlot);
m_Graph.RemoveNode(node);
}
return true;
}
bool OnConvertToInlineNode()
{
if (m_GraphView == null)
return false;
var selectedNodeViews = m_GraphView.selection.OfType<MaterialNodeView>()
.Select(x => x.node)
.OfType<PropertyNode>();
foreach (var propNode in selectedNodeViews)
((AbstractMaterialGraph)propNode.owner).ReplacePropertyNodeWithConcreteNode(propNode);
return true;
}
bool OnAddNode(SearchTreeEntry entry, SearchWindowContext context)
{
Type type;
var asset = entry.userData as MaterialSubGraphAsset;

4
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/GraphEditorView.cs


public Action onConvertToSubgraphClick
{
get { return m_SearchWindowProvider.onConvertToSubgraphClick; }
set { m_SearchWindowProvider.onConvertToSubgraphClick = value; }
get { return m_GraphView.onConvertToSubgraphClick; }
set { m_GraphView.onConvertToSubgraphClick = value; }
}
public Action onShowInProjectClick

80
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialGraphView.cs


public sealed class MaterialGraphView : GraphView
{
public AbstractMaterialGraph graph { get; private set; }
public Action onConvertToSubgraphClick { get; set; }
public override List<Port> GetCompatiblePorts(Port startAnchor, NodeAdapter nodeAdapter)
{

compatibleAnchors.Add(candidateAnchor);
}
return compatibleAnchors;
}
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
base.BuildContextualMenu(evt);
evt.menu.AppendSeparator();
evt.menu.AppendAction("Convert To Sub-graph", ConvertToSubgraph, ConvertToSubgraphStatus);
evt.menu.AppendAction("Convert To Inline Node", ConvertToInlineNode, ConvertToInlineNodeStatus);
evt.menu.AppendAction("Convert To Property", ConvertToProperty, ConvertToPropertyStatus);
}
ContextualMenu.MenuAction.StatusFlags ConvertToPropertyStatus(EventBase eventBase)
{
if (selection.OfType<MaterialNodeView>().Any(v => v.node != null))
{
if (selection.OfType<MaterialNodeView>().Any(v => v.node is IPropertyFromNode))
return ContextualMenu.MenuAction.StatusFlags.Normal;
return ContextualMenu.MenuAction.StatusFlags.Disabled;
}
return ContextualMenu.MenuAction.StatusFlags.Hidden;
}
void ConvertToProperty(EventBase eventBase)
{
var selectedNodeViews = selection.OfType<MaterialNodeView>().Select(x => x.node).ToList();
foreach (var node in selectedNodeViews)
{
if (!(node is IPropertyFromNode))
continue;
var converter = node as IPropertyFromNode;
var prop = converter.AsShaderProperty();
graph.AddShaderProperty(prop);
var propNode = new PropertyNode();
propNode.drawState = node.drawState;
graph.AddNode(propNode);
propNode.propertyGuid = prop.guid;
var oldSlot = node.FindSlot<MaterialSlot>(converter.outputSlotId);
var newSlot = propNode.FindSlot<MaterialSlot>(PropertyNode.OutputSlotId);
foreach (var edge in graph.GetEdges(oldSlot.slotReference))
graph.Connect(newSlot.slotReference, edge.inputSlot);
graph.RemoveNode(node);
}
}
ContextualMenu.MenuAction.StatusFlags ConvertToInlineNodeStatus(EventBase eventBase)
{
if (selection.OfType<MaterialNodeView>().Any(v => v.node != null))
{
if (selection.OfType<MaterialNodeView>().Any(v => v.node is PropertyNode))
return ContextualMenu.MenuAction.StatusFlags.Normal;
return ContextualMenu.MenuAction.StatusFlags.Disabled;
}
return ContextualMenu.MenuAction.StatusFlags.Hidden;
}
void ConvertToInlineNode(EventBase eventBase)
{
var selectedNodeViews = selection.OfType<MaterialNodeView>()
.Select(x => x.node)
.OfType<PropertyNode>();
foreach (var propNode in selectedNodeViews)
((AbstractMaterialGraph)propNode.owner).ReplacePropertyNodeWithConcreteNode(propNode);
}
ContextualMenu.MenuAction.StatusFlags ConvertToSubgraphStatus(EventBase eventBase)
{
if (onConvertToSubgraphClick == null) return ContextualMenu.MenuAction.StatusFlags.Hidden;
return selection.OfType<MaterialNodeView>().Any(v => v.node != null) ? ContextualMenu.MenuAction.StatusFlags.Normal : ContextualMenu.MenuAction.StatusFlags.Hidden;
}
void ConvertToSubgraph(EventBase eventBase)
{
onConvertToSubgraphClick();
}
public delegate void OnSelectionChanged(IEnumerable<INode> nodes);

31
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Views/MaterialNodeView.cs


}
}
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
{
if (evt.target is Node)
evt.menu.AppendAction("Copy shader", ConvertToShader, ConvertToShaderStatus);
base.BuildContextualMenu(evt);
}
ContextualMenu.MenuAction.StatusFlags ConvertToShaderStatus(EventBase eventBase)
{
return node.hasPreview ? ContextualMenu.MenuAction.StatusFlags.Normal : ContextualMenu.MenuAction.StatusFlags.Hidden;
}
void ConvertToShader(EventBase eventBase)
{
List<PropertyCollector.TextureInfo> textureInfo;
var masterNode = node as MasterNode;
if (masterNode != null)
{
var shader = masterNode.GetShader(GenerationMode.ForReals, masterNode.name, out textureInfo);
GUIUtility.systemCopyBuffer = shader;
}
else
{
PreviewMode previewMode;
FloatShaderProperty outputIdProperty;
var graph = (AbstractMaterialGraph)node.owner;
var shader = graph.GetShader(node, GenerationMode.ForReals, node.name, out textureInfo, out previewMode, out outputIdProperty);
GUIUtility.systemCopyBuffer = shader;
}
}
void UpdatePreviewExpandedState(bool expanded)
{
node.previewExpanded = expanded;

正在加载...
取消
保存