/// <summary> /// Constructor</summary> /// <param name="node">The node the context will be editing</param> public RangeSliderValueEditorContext(PropertyNode node) : base(node) { RangeStart = Min; RangeStop = Max; RangeEnabled = true; }
private void CheckProperty(PropertyNode p) { if (p == null) return; CheckType(p.Type, p); }
private static object GetEditorKey(PropertyNode node, bool editable, EditorKeyType keyType) { Type propertyType = node.PropertyType; object obj2 = node.Value; if (editable && propertyType != null) { if (propertyType == typeof(bool)) { if (keyType == EditorKeyType.Style) return PropertyGrid.BoolEditorStyleKey; return PropertyGrid.BoolEditorTemplateKey; } if (((propertyType != null) && node.StandardValues != null)) { if (keyType == EditorKeyType.Style) return PropertyGrid.ComboEditorStyleKey; return PropertyGrid.ComboEditorTemplateKey; } if (s_simpleTypes.Contains(propertyType)) { if (keyType == EditorKeyType.Style) return PropertyGrid.DefaultTextEditorStyleKey; return PropertyGrid.DefaultTextEditorTemplateKey; } } if (keyType == EditorKeyType.Style) return PropertyGrid.ReadOnlyStyleKey; return PropertyGrid.ReadOnlyTemplateKey; }
/// <summary> /// Constructor</summary> /// <param name="node">The node the context will be editing</param> /// <param name="editor">The editor, which provides the Filter and DefaultExtension information</param> public FilePathValueEditorContext(PropertyNode node, FilePathValueEditor editor) { m_node = node; Filter = editor.Filter; DefaultExtension = editor.DefaultExtension; }
/// <summary> /// Gets custom context for PropertyNode</summary> /// <param name="node">PropertyNode </param> /// <returns>New custom context for PropertyNode</returns> public override object GetCustomContext(PropertyNode node) { if (node == null) return null; if (m_minimum.IsNaN() || m_maximum.IsNaN()) // if range is not set return new SliderValueEditorContext(node); return new SliderValueEditorContext(node, m_minimum, m_maximum, true); }
/// <summary> /// Constructor</summary> /// <param name="node">Property node</param> public SliderValueEditorContext(PropertyNode node) { Node = node; Node.ValueChanged += OnNodeOnValueChanged; var numberRange = Node.Descriptor.Attributes[typeof(NumberRangesAttribute)] as NumberRangesAttribute; if (numberRange != null) { m_max = numberRange.Maximum; m_min = numberRange.Minimum; m_center = numberRange.Center; m_hardMin = numberRange.HardMinimum; m_hardMax = numberRange.HardMaximum; } else { var dataRange = Node.Descriptor.Attributes[typeof(RangeAttribute)] as RangeAttribute; if (dataRange != null) { m_max = Convert.ToDouble(dataRange.Minimum); m_min = Convert.ToDouble(dataRange.Maximum); m_center = (m_max - m_min) / 2.0; } } var defaultValue = Node.Descriptor.Attributes[typeof(DefaultValueAttribute)] as DefaultValueAttribute; if (defaultValue != null) { if (defaultValue.Value.GetType().IsValueType) m_default = Convert.ToDouble(defaultValue.Value); } var numberInc = Node.Descriptor.Attributes[typeof(NumberIncrementsAttribute)] as NumberIncrementsAttribute; if (numberInc != null) { m_smallChange = numberInc.SmallChange; m_defaultChange = numberInc.DefaultChange; m_largeChange = numberInc.LargeChange; m_isLogarithmic = numberInc.IsLogarithimc; } var units = Node.Descriptor.Attributes[typeof(DisplayUnitsAttribute)] as DisplayUnitsAttribute; if (units != null) { m_units = units.Units; } var numberFormat = Node.Descriptor.Attributes[typeof(NumberFormatAttribute)] as NumberFormatAttribute; if (numberFormat != null) { m_scale = numberFormat.Scale ?? 1.0; m_formatString = numberFormat.FormatString; } Update(); }
private void SetNode(PropertyNode node) { m_node = node; var attribute = m_node.Descriptor.Attributes[typeof(ImageListAttribute)] as ImageListAttribute; if (attribute != null) { m_imageList = attribute.ImageKeys; } }
private static DataTemplate GetDefaultTemplate(PropertyNode node) { if (node != null) { object key = GetEditorKey(node, node.IsWriteable, EditorKeyType.Template); if (key != null) return Application.Current.FindResource(key) as DataTemplate; } return null; }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Constructor. </summary> /// /// <param name="parentNode"> The parent node. </param> public ExtractorPathSettings(PropertyNode parentNode) : base(parentNode) { if (!parentNode.Has("TagsFolder")) { TagsFolder = ""; } if (!parentNode.Has("DataFolder")) { DataFolder = ""; } }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Constructor. </summary> /// /// <param name="parentNode"> The parent node. </param> public LightmapImporterSettings(PropertyNode parentNode) : base(parentNode) { if (!parentNode.Has("TagsFolder")) { TagsFolder = ""; } if (!parentNode.Has("DataFolder")) { DataFolder = ""; } }
/// <summary> /// Constructor</summary> /// <param name="node">PropertyNode</param> public SliderValueEditorContext(PropertyNode node) { m_node = node; m_node.ValueChanged += new EventHandler(Node_ValueChanged); Update(); NumberRangesAttribute numberRange = m_node.Descriptor.Attributes[typeof(NumberRangesAttribute)] as NumberRangesAttribute; if (numberRange != null) { Max = numberRange.Maximum; Min = numberRange.Minimum; } else { Max = double.MaxValue; Min = double.MinValue; } NumberIncrementsAttribute numberInc = m_node.Descriptor.Attributes[typeof(NumberIncrementsAttribute)] as NumberIncrementsAttribute; if (numberInc != null) { SmallChange = numberInc.SmallChange; LargeChange = numberInc.LargeChange; } else { SmallChange = 1; LargeChange = 10; } NumberFormatAttribute numberFormat = m_node.Descriptor.Attributes[typeof(NumberFormatAttribute)] as NumberFormatAttribute; if (numberFormat != null) { FormatString = numberFormat.FormatString; } else { FormatString = "{0:0.00}"; } }
public PropertyNode CreateProperty(object instance, PropertyDescriptor descriptor, bool isEnumerable, ITransactionContext context) { var node = new PropertyNode(); node.Initialize(instance, descriptor, isEnumerable); // set up value editors if (descriptor.Name == "Price" && descriptor.PropertyType == typeof (float)) { var items = (object[])instance; var item = (Suv)items[0]; var valueEditor = new SliderValueEditor(); valueEditor.SetRange(item.Min, item.Max); node.SetCustomEditor(valueEditor); } return node; }
private static void _PopName(IList<string> nameStack, PropertyNode current) { if (0 != nameStack.Count && !SchemaStrings.SkipPropertyName(current.LocalName)) { NodeTypes type = current.ContactNodeType; if (type == NodeTypes.ElementCollection || type == NodeTypes.ElementNode) { string nodeName = current.LocalName; if (type == NodeTypes.ElementNode) { nodeName += "[" + current.Parent.Children.Count.ToString("G", null) + "]"; } if (nameStack[nameStack.Count - 1] == nodeName) { nameStack.RemoveAt(nameStack.Count - 1); } } } }
private static void _PushName(IList<string> nameStack, PropertyNode current) { if (!SchemaStrings.SkipPropertyName(current.LocalName)) { NodeTypes type = current.ContactNodeType; if (type == NodeTypes.ElementCollection || type == NodeTypes.ElementNode) { string nodeName = current.LocalName; if (type == NodeTypes.ElementNode) { nodeName += "[" + current.Parent.Children.Count.ToString("G", null) + "]"; Assert.AreNotEqual(0, nameStack.Count); } if (nameStack.Count == 0 || nameStack[nameStack.Count - 1] != nodeName) { nameStack.Add(nodeName); } } } }
public MapCompressorSettings(PropertyNode parentNode) : base(parentNode) { if (!parentNode.Has("MapsFolder")) { MapsFolder = ""; } if (!parentNode.Has("PartsFolder")) { PartsFolder = ""; } if (!parentNode.Has("DefinitionsFolder")) { DefinitionsFolder = ""; } if (!parentNode.Has("EncryptArchive")) { EncryptArchive = false; } ServerPassword = ""; }
public object this[string propertyName] { get { PropertyNode node = GetNode(propertyName); if ( node == null ) throw new KeyNotFoundException(string.Format("Property with name: {0} is not defined in the object", propertyName)); return node.m_value; } set { // If node is not present we need to create one // If exists, update the value PropertyNode node = GetNode(propertyName); if ( node == null ) { node = new PropertyNode() { m_value = value }; m_properties.Add(propertyName, node); // Add a new node to the dictionary } else { // // Whetever this node defines the event for updating the current value, invoke that event handler if ( node.m_beforeValueChanged != null ) node.m_beforeValueChanged(propertyName, node.m_value); // invoke with old value node.m_value = value; // Update existing node value if ( node.m_afterValueChanged != null ) node.m_afterValueChanged(propertyName, value); // invoke with new value } } }
public override object GetCustomContext(PropertyNode node) { return((node == null) ? null : new StandardValuesEditorContext(node, AppearanceService.RegisteredSkins.Select(x => x.Name))); }
/// <summary> /// Gets custom context for PropertyNode</summary> /// <param name="node">PropertyNode </param> /// <returns>New custom context for PropertyNode</returns> public override object GetCustomContext(PropertyNode node) { if(node != null) return new SliderValueEditorContext(node); return null; }
public override DataTemplate GetTemplate(PropertyNode node, DependencyObject container) { return(FindResource <DataTemplate>(PropertyGrid.StandardValuesEditorTemplateKey, container)); }
/// <summary> /// Get the property setting of common setting dialog. /// </summary> /// <returns>the list of property setting.</returns> public override List<IPropertyItem> GetPropertySettings() { PropertyNode node = new PropertyNode(MessageResources.NameGraphSetting); node.Nodes.Add(new PropertyNode(new TracerConfigurationPage(this, this.PlotNumber, this.RedrawInterval, m_setting.Copy()))); List<IPropertyItem> nodeList = new List<IPropertyItem>(); nodeList.Add(node); return nodeList; }
/// <summary> /// Corrects the IContact naming of element nodes. Call this after modifying a collection's children. /// </summary> /// <param name="collectionNode">The collection node that needs its children fixed up.</param> /// <param name="nodeName">The name to use for the children nodes.</param> private void _FixupChildren(PropertyNode collectionNode, string nodeName) { Assert.IsNotNull(collectionNode); Assert.IsNeitherNullNorEmpty(nodeName); // First pass, remove everything from the lookup table and update the names. int printIndex = 1; foreach (PropertyNode child in collectionNode.Children) { // Only expecting this to be used to correct indices. Assert.IsTrue( string.IsNullOrEmpty(child.IContactName) || (child.IContactName.StartsWith(collectionNode.IContactName + "/" + nodeName, StringComparison.Ordinal) && child.IContactName.EndsWith("]", StringComparison.Ordinal))); string newName = string.Format(null, "{0}/{1}[{2}]", collectionNode.IContactName, nodeName, printIndex); _contactTree.Lookup.Remove(child); child.IContactName = newName; ++printIndex; } // Second pass, add back to the lookup table with the correct names. foreach (PropertyNode child in collectionNode.Children) { _contactTree.Lookup.Add(child); } }
private string _CreateSimpleArrayNode(string collectionName, bool appendNode) { Assert.IsNeitherNullNorEmpty(collectionName); Assert.AreEqual('[', collectionName[0]); var token = new PropertyNameInfo(collectionName); if (token.Type != PropertyNameTypes.SimpleExtensionCreationProperty) { throw new ArgumentException("The property name is improperly formatted for creating a new simple extension node."); } Assert.IsNeitherNullNorEmpty(token.Level1); Assert.IsNeitherNullNorEmpty(token.Level2); Assert.IsNeitherNullNorEmpty(token.SimpleExtensionNamespace); PropertyNode collectionNode = _EnsureSimpleCollection(token.SimpleExtensionNamespace, token.Level1); string xmlPrefix = collectionNode.ExtendedNamespacePrefix.Substring(1, collectionNode.ExtendedNamespacePrefix.Length - 2); XmlElement nodeElement = _document.CreateElement(xmlPrefix, token.Level2, collectionNode.ExtendedNamespace); // New nodes are set to nil. Version is implicitly "1". XmlAttribute elementIdAttribute = _namespaceManager.CreateElementIdAttribute(); elementIdAttribute.Value = Guid.NewGuid().ToString(); XmlAttribute typeAttribute = _namespaceManager.CreateNodeTypeAttribute(SchemaStrings.SchemaTypeArrayNode); nodeElement.Attributes.Append(elementIdAttribute); nodeElement.Attributes.Append(typeAttribute); _namespaceManager.AddNilAttribute(nodeElement); _namespaceManager.UpdateVersionAndModificationDate(nodeElement); PropertyNode newNode = null; // Now modifying the DOM (probably modified it by creating the collection earlier, too...). _SetUnusableOnException( () => { if (appendNode) { collectionNode.XmlNode.AppendChild(nodeElement); } else { collectionNode.XmlNode.PrependChild(nodeElement); } // ??? _contactTree.AdjustTree(); newNode = new PropertyNode(nodeElement, collectionNode, appendNode) {Version = 1}; _FixupChildren(collectionNode, token.Level2); }, null); _SuperExpensiveDeepValidate(this); Assert.IsNeitherNullNorEmpty(newNode.IContactName); return newNode.IContactName; }
/// <summary> /// Creates a new array node for a schematized collection. Also creates the collection if necessary. /// </summary> /// <param name="collectionName">The collection to create the new node in.</param> /// <param name="appendNode">Whether to append or prepend the new node in the collection.</param> /// <returns>The name of the new node.</returns> /// <remarks> /// The array node name is inferred since this is only used for known collections. /// </remarks> private string _CreateSchematizedArrayNode(string collectionName, bool appendNode) { string arrayNodeName = SchemaStrings.TryGetCollectionNodeName(collectionName); if (string.IsNullOrEmpty(arrayNodeName)) { throw new SchemaException(collectionName + " is not a valid collection name."); } PropertyNode newPNode = null; // About to start modifying the DOM tree. // If we fail we need to successfully roll back any changes to keep the object usable. _SetUnusableOnException( () => { // TODO: To successfully rollback here we need to know whether the collection was added, // since an empty collection will generally violate the XSD. PropertyNode collectionPNode = _EnsureCollection(collectionName); XmlElement arrayXNode = _namespaceManager.CreateSchemaElement(arrayNodeName); XmlAttribute elementIdAttribute = _namespaceManager.CreateElementIdAttribute(); elementIdAttribute.Value = Guid.NewGuid().ToString(); arrayXNode.Attributes.Append(elementIdAttribute); _namespaceManager.AddNilAttribute(arrayXNode); _namespaceManager.UpdateVersionAndModificationDate(arrayXNode); if (appendNode) { collectionPNode.XmlNode.AppendChild(arrayXNode); } else { collectionPNode.XmlNode.PrependChild(arrayXNode); } // This function shouldn't be able to do anything that causes an invalid document. Assert.Evaluate(_ValidateDom); // ??? _contactTree.AdjustTree newPNode = new PropertyNode(arrayXNode, collectionPNode, appendNode) { Version = 1 }; _FixupChildren(collectionPNode, arrayNodeName); }, null); Assert.Evaluate(() => _document.Validate((sender, e) => Assert.Fail())); _SuperExpensiveDeepValidate(this); Assert.IsNeitherNullNorEmpty(newPNode.IContactName); return newPNode.IContactName; }
void CreateNode(object obj, Vector2 nodePosition) { var texture2D = obj as Texture2D; if (texture2D != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture"); bool isNormalMap = false; if (EditorUtility.IsPersistent(texture2D) && !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(texture2D))) { var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture2D)) as TextureImporter; if (importer != null) { isNormalMap = importer.textureType == TextureImporterType.NormalMap; } } var node = new SampleTexture2DNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); if (isNormalMap) { node.textureType = TextureType.Normal; } var inputslot = node.FindInputSlot <Texture2DInputMaterialSlot>(SampleTexture2DNode.TextureInputId); if (inputslot != null) { inputslot.texture = texture2D; } } var textureArray = obj as Texture2DArray; if (textureArray != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture Array"); var property = new Texture2DArrayShaderProperty { displayName = textureArray.name, value = { textureArray = textureArray } }; graph.AddShaderProperty(property); var node = new SampleTexture2DArrayNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindSlot <Texture2DArrayInputMaterialSlot>(SampleTexture2DArrayNode.TextureInputId); if (inputslot != null) { inputslot.textureArray = textureArray; } } var texture3D = obj as Texture3D; if (texture3D != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture 3D"); var property = new Texture3DShaderProperty { displayName = texture3D.name, value = { texture = texture3D } }; graph.AddShaderProperty(property); var node = new SampleTexture3DNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindSlot <Texture3DInputMaterialSlot>(SampleTexture3DNode.TextureInputId); if (inputslot != null) { inputslot.texture = texture3D; } } var cubemap = obj as Cubemap; if (cubemap != null) { graph.owner.RegisterCompleteObjectUndo("Drag Cubemap"); var property = new CubemapShaderProperty { displayName = cubemap.name, value = { cubemap = cubemap } }; graph.AddShaderProperty(property); var node = new SampleCubemapNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindInputSlot <CubemapInputMaterialSlot>(SampleCubemapNode.CubemapInputId); if (inputslot != null) { inputslot.cubemap = cubemap; } } var subGraphAsset = obj as SubGraphAsset; if (subGraphAsset != null) { graph.owner.RegisterCompleteObjectUndo("Drag Sub-Graph"); var node = new SubGraphNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; node.subGraphAsset = subGraphAsset; graph.AddNode(node); } var blackboardField = obj as BlackboardField; if (blackboardField != null) { AbstractShaderProperty property = blackboardField.userData as AbstractShaderProperty; if (property != null) { graph.owner.RegisterCompleteObjectUndo("Drag Property"); var node = new PropertyNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); // Setting the guid requires the graph to be set first. node.propertyGuid = property.guid; } } }
public void ToSubGraph() { var graphView = graphEditorView.graphView; string path; string sessionStateResult = SessionState.GetString(k_PrevSubGraphPathKey, k_PrevSubGraphPathDefaultValue); string pathToOriginSG = Path.GetDirectoryName(AssetDatabase.GUIDToAssetPath(selectedGuid)); if (!sessionStateResult.Equals(k_PrevSubGraphPathDefaultValue)) { path = sessionStateResult; } else { path = pathToOriginSG; } path = EditorUtility.SaveFilePanelInProject("Save Sub Graph", "New Shader Sub Graph", ShaderSubGraphImporter.Extension, "", path); path = path.Replace(Application.dataPath, "Assets"); // Friendly warning that the user is generating a subgraph that would overwrite the one they are currently working on. if (AssetDatabase.AssetPathToGUID(path) == selectedGuid) { if (!EditorUtility.DisplayDialog("Overwrite Current Subgraph", "Do you want to overwrite this Sub Graph that you are currently working on? You cannot undo this operation.", "Yes", "Cancel")) { path = ""; } } if (path.Length == 0) { return; } var nodes = graphView.selection.OfType <IShaderNodeView>().Where(x => !(x.node is PropertyNode || x.node is SubGraphOutputNode)).Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(); // Convert To Subgraph could create recursive reference loops if the target path already exists // Let's check for that here if (!string.IsNullOrEmpty(path)) { if (GraphUtil.CheckForRecursiveDependencyOnPendingSave(path, nodes.OfType <SubGraphNode>(), "Convert To SubGraph")) { return; } } graphObject.RegisterCompleteObjectUndo("Convert To Subgraph"); var bounds = Rect.MinMaxRect(float.PositiveInfinity, float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity); foreach (var node in nodes) { var center = node.drawState.position.center; bounds = Rect.MinMaxRect( Mathf.Min(bounds.xMin, center.x), Mathf.Min(bounds.yMin, center.y), Mathf.Max(bounds.xMax, center.x), Mathf.Max(bounds.yMax, center.y)); } var middle = bounds.center; bounds.center = Vector2.zero; // Collect graph inputs var graphInputs = graphView.selection.OfType <BlackboardField>().Select(x => x.userData as ShaderInput); // Collect the property nodes and get the corresponding properties var propertyNodes = graphView.selection.OfType <IShaderNodeView>().Where(x => (x.node is PropertyNode)).Select(x => ((PropertyNode)x.node).property); var metaProperties = graphView.graph.properties.Where(x => propertyNodes.Contains(x)); // Collect the keyword nodes and get the corresponding keywords var keywordNodes = graphView.selection.OfType <IShaderNodeView>().Where(x => (x.node is KeywordNode)).Select(x => ((KeywordNode)x.node).keyword); var metaKeywords = graphView.graph.keywords.Where(x => keywordNodes.Contains(x)); var copyPasteGraph = new CopyPasteGraph(graphView.selection.OfType <ShaderGroup>().Select(x => x.userData), graphView.selection.OfType <IShaderNodeView>().Where(x => !(x.node is PropertyNode || x.node is SubGraphOutputNode)).Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(), graphView.selection.OfType <Edge>().Select(x => x.userData as Graphing.Edge), graphInputs, metaProperties, metaKeywords, graphView.selection.OfType <StickyNote>().Select(x => x.userData), true); // why do we serialize and deserialize only to make copies of everything in the steps below? // is this just to clear out all non-serialized data? var deserialized = CopyPasteGraph.FromJson(MultiJson.Serialize(copyPasteGraph), graphView.graph); if (deserialized == null) { return; } var subGraph = new GraphData { isSubGraph = true, path = "Sub Graphs" }; var subGraphOutputNode = new SubGraphOutputNode(); { var drawState = subGraphOutputNode.drawState; drawState.position = new Rect(new Vector2(bounds.xMax + 200f, 0f), drawState.position.size); subGraphOutputNode.drawState = drawState; } subGraph.AddNode(subGraphOutputNode); subGraph.outputNode = subGraphOutputNode; // Always copy deserialized keyword inputs foreach (ShaderKeyword keyword in deserialized.metaKeywords) { var copiedInput = (ShaderKeyword)keyword.Copy(); subGraph.SanitizeGraphInputName(copiedInput); subGraph.SanitizeGraphInputReferenceName(copiedInput, keyword.overrideReferenceName); subGraph.AddGraphInput(copiedInput); // Update the keyword nodes that depends on the copied keyword var dependentKeywordNodes = deserialized.GetNodes <KeywordNode>().Where(x => x.keyword == keyword); foreach (var node in dependentKeywordNodes) { node.owner = graphView.graph; node.keyword = copiedInput; } } foreach (GroupData groupData in deserialized.groups) { subGraph.CreateGroup(groupData); } foreach (var node in deserialized.GetNodes <AbstractMaterialNode>()) { var drawState = node.drawState; drawState.position = new Rect(drawState.position.position - middle, drawState.position.size); node.drawState = drawState; // Checking if the group guid is also being copied. // If not then nullify that guid if (node.group != null && !subGraph.groups.Contains(node.group)) { node.group = null; } subGraph.AddNode(node); } foreach (var note in deserialized.stickyNotes) { if (note.group != null && !subGraph.groups.Contains(note.group)) { note.group = null; } subGraph.AddStickyNote(note); } // figure out what needs remapping var externalOutputSlots = new List <Graphing.Edge>(); var externalInputSlots = new List <Graphing.Edge>(); foreach (var edge in deserialized.edges) { var outputSlot = edge.outputSlot; var inputSlot = edge.inputSlot; var outputSlotExistsInSubgraph = subGraph.ContainsNode(outputSlot.node); var inputSlotExistsInSubgraph = subGraph.ContainsNode(inputSlot.node); // pasting nice internal links! if (outputSlotExistsInSubgraph && inputSlotExistsInSubgraph) { subGraph.Connect(outputSlot, inputSlot); } // one edge needs to go to outside world else if (outputSlotExistsInSubgraph) { externalInputSlots.Add(edge); } else if (inputSlotExistsInSubgraph) { externalOutputSlots.Add(edge); } } // Find the unique edges coming INTO the graph var uniqueIncomingEdges = externalOutputSlots.GroupBy( edge => edge.outputSlot, edge => edge, (key, edges) => new { slotRef = key, edges = edges.ToList() }); var externalInputNeedingConnection = new List <KeyValuePair <IEdge, AbstractShaderProperty> >(); var amountOfProps = uniqueIncomingEdges.Count(); const int height = 40; const int subtractHeight = 20; var propPos = new Vector2(0, -((amountOfProps / 2) + height) - subtractHeight); foreach (var group in uniqueIncomingEdges) { var sr = group.slotRef; var fromNode = sr.node; var fromSlot = sr.slot; var materialGraph = graphObject.graph; var fromProperty = fromNode is PropertyNode fromPropertyNode ? materialGraph.properties.FirstOrDefault(p => p == fromPropertyNode.property) : null; AbstractShaderProperty prop; switch (fromSlot.concreteValueType) { case ConcreteSlotValueType.Texture2D: prop = new Texture2DShaderProperty(); break; case ConcreteSlotValueType.Texture2DArray: prop = new Texture2DArrayShaderProperty(); break; case ConcreteSlotValueType.Texture3D: prop = new Texture3DShaderProperty(); break; case ConcreteSlotValueType.Cubemap: prop = new CubemapShaderProperty(); break; case ConcreteSlotValueType.Vector4: prop = new Vector4ShaderProperty(); break; case ConcreteSlotValueType.Vector3: prop = new Vector3ShaderProperty(); break; case ConcreteSlotValueType.Vector2: prop = new Vector2ShaderProperty(); break; case ConcreteSlotValueType.Vector1: prop = new Vector1ShaderProperty(); break; case ConcreteSlotValueType.Boolean: prop = new BooleanShaderProperty(); break; case ConcreteSlotValueType.Matrix2: prop = new Matrix2ShaderProperty(); break; case ConcreteSlotValueType.Matrix3: prop = new Matrix3ShaderProperty(); break; case ConcreteSlotValueType.Matrix4: prop = new Matrix4ShaderProperty(); break; case ConcreteSlotValueType.SamplerState: prop = new SamplerStateShaderProperty(); break; case ConcreteSlotValueType.Gradient: prop = new GradientShaderProperty(); break; case ConcreteSlotValueType.VirtualTexture: prop = new VirtualTextureShaderProperty() { // also copy the VT settings over from the original property (if there is one) value = (fromProperty as VirtualTextureShaderProperty)?.value ?? new SerializableVirtualTexture() }; break; default: throw new ArgumentOutOfRangeException(); } prop.displayName = fromProperty != null ? fromProperty.displayName : fromSlot.concreteValueType.ToString(); prop.displayName = GraphUtil.SanitizeName(subGraph.addedInputs.Select(p => p.displayName), "{0} ({1})", prop.displayName); subGraph.AddGraphInput(prop); var propNode = new PropertyNode(); { var drawState = propNode.drawState; drawState.position = new Rect(new Vector2(bounds.xMin - 300f, 0f) + propPos, drawState.position.size); propPos += new Vector2(0, height); propNode.drawState = drawState; } subGraph.AddNode(propNode); propNode.property = prop; foreach (var edge in group.edges) { subGraph.Connect( new SlotReference(propNode, PropertyNode.OutputSlotId), edge.inputSlot); externalInputNeedingConnection.Add(new KeyValuePair <IEdge, AbstractShaderProperty>(edge, prop)); } } var uniqueOutgoingEdges = externalInputSlots.GroupBy( edge => edge.outputSlot, edge => edge, (key, edges) => new { slot = key, edges = edges.ToList() }); var externalOutputsNeedingConnection = new List <KeyValuePair <IEdge, IEdge> >(); foreach (var group in uniqueOutgoingEdges) { var outputNode = subGraph.outputNode as SubGraphOutputNode; AbstractMaterialNode node = group.edges[0].outputSlot.node; MaterialSlot slot = node.FindSlot <MaterialSlot>(group.edges[0].outputSlot.slotId); var slotId = outputNode.AddSlot(slot.concreteValueType); var inputSlotRef = new SlotReference(outputNode, slotId); foreach (var edge in group.edges) { var newEdge = subGraph.Connect(edge.outputSlot, inputSlotRef); externalOutputsNeedingConnection.Add(new KeyValuePair <IEdge, IEdge>(edge, newEdge)); } } if (FileUtilities.WriteShaderGraphToDisk(path, subGraph) != null) { AssetDatabase.ImportAsset(path); } // Store path for next time if (!pathToOriginSG.Equals(Path.GetDirectoryName(path))) { SessionState.SetString(k_PrevSubGraphPathKey, Path.GetDirectoryName(path)); } else { // Or continue to make it so that next time it will open up in the converted-from SG's directory SessionState.EraseString(k_PrevSubGraphPathKey); } var loadedSubGraph = AssetDatabase.LoadAssetAtPath(path, typeof(SubGraphAsset)) as SubGraphAsset; if (loadedSubGraph == null) { return; } var subGraphNode = new SubGraphNode(); var ds = subGraphNode.drawState; ds.position = new Rect(middle - new Vector2(100f, 150f), Vector2.zero); subGraphNode.drawState = ds; // Add the subgraph into the group if the nodes was all in the same group group var firstNode = copyPasteGraph.GetNodes <AbstractMaterialNode>().FirstOrDefault(); if (firstNode != null && copyPasteGraph.GetNodes <AbstractMaterialNode>().All(x => x.group == firstNode.group)) { subGraphNode.group = firstNode.group; } subGraphNode.asset = loadedSubGraph; graphObject.graph.AddNode(subGraphNode); foreach (var edgeMap in externalInputNeedingConnection) { graphObject.graph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode, edgeMap.Value.guid.GetHashCode())); } foreach (var edgeMap in externalOutputsNeedingConnection) { graphObject.graph.Connect(new SlotReference(subGraphNode, edgeMap.Value.inputSlot.slotId), edgeMap.Key.inputSlot); } graphObject.graph.RemoveElements( graphView.selection.OfType <IShaderNodeView>().Select(x => x.node).Where(x => x.allowedInSubGraph).ToArray(), new IEdge[] {}, new GroupData[] {}, graphView.selection.OfType <StickyNote>().Select(x => x.userData).ToArray()); graphObject.graph.ValidateGraph(); }
public virtual bool Visit <T, TProperty, TValue>(PropertyNode <T, TProperty, TValue> node, Func <RuntimeVisitor, bool> next) where T : class { return(next(this)); }
protected internal override void VisitProperty(PropertyNode node) { //We don't want to include property values }
protected virtual void VisitPropertyNode(PropertyNode node) { }
public PropertyNodeCreator(ModuleDocumentNode modNode, TypeNode ownerNode, PropertyDef property) { this.ownerNode = ownerNode; propNode = modNode.Context.DocumentTreeView.Create(property); }
void CreateNode(object obj, Vector2 nodePosition) { var texture2D = obj as Texture2D; if (texture2D != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture"); bool isNormalMap = false; if (EditorUtility.IsPersistent(texture2D) && !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(texture2D))) { var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture2D)) as TextureImporter; if (importer != null) { isNormalMap = importer.textureType == TextureImporterType.NormalMap; } } var node = new SampleTexture2DNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); if (isNormalMap) { node.textureType = TextureType.Normal; } var inputslot = node.FindInputSlot <Texture2DInputMaterialSlot>(SampleTexture2DNode.TextureInputId); if (inputslot != null) { inputslot.texture = texture2D; } } var textureArray = obj as Texture2DArray; if (textureArray != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture Array"); var node = new SampleTexture2DArrayNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindSlot <Texture2DArrayInputMaterialSlot>(SampleTexture2DArrayNode.TextureInputId); if (inputslot != null) { inputslot.textureArray = textureArray; } } var texture3D = obj as Texture3D; if (texture3D != null) { graph.owner.RegisterCompleteObjectUndo("Drag Texture 3D"); var node = new SampleTexture3DNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindSlot <Texture3DInputMaterialSlot>(SampleTexture3DNode.TextureInputId); if (inputslot != null) { inputslot.texture = texture3D; } } var cubemap = obj as Cubemap; if (cubemap != null) { graph.owner.RegisterCompleteObjectUndo("Drag Cubemap"); var node = new SampleCubemapNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); var inputslot = node.FindInputSlot <CubemapInputMaterialSlot>(SampleCubemapNode.CubemapInputId); if (inputslot != null) { inputslot.cubemap = cubemap; } } var subGraphAsset = obj as SubGraphAsset; if (subGraphAsset != null) { graph.owner.RegisterCompleteObjectUndo("Drag Sub-Graph"); var node = new SubGraphNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; node.asset = subGraphAsset; graph.AddNode(node); } var blackboardField = obj as BlackboardField; if (blackboardField != null) { graph.owner.RegisterCompleteObjectUndo("Drag Graph Input"); switch (blackboardField.userData) { case AbstractShaderProperty property: { var node = new PropertyNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); // Setting the guid requires the graph to be set first. node.propertyGuid = property.guid; break; } case ShaderKeyword keyword: { var node = new KeywordNode(); var drawState = node.drawState; drawState.position = new Rect(nodePosition, drawState.position.size); node.drawState = drawState; graph.AddNode(node); // Setting the guid requires the graph to be set first. node.keywordGuid = keyword.guid; break; } default: throw new ArgumentOutOfRangeException(); } } }
/// <summary> /// Rebuild property nodes implementation function</summary> protected virtual void RebuildPropertyNodesImpl() { DestroyPropertyNodes(); object[] instances = Instances == null ? EmptyArray<object>.Instance : Instances.Cast<object>().ToArray(); // TODO: cache and reuse PropertyNodes where possible to prevent having to // rebuild all of the data templates IEnumerable<PropertyDescriptor> descriptors = null; if (CustomPropertyDescriptors != null) { descriptors = CustomPropertyDescriptors; } else if (Instances != null) { descriptors = PropertyUtils.GetSharedPropertiesOriginal(instances); } PropertyNode headerPropertyNode = null; var propertyNodes = new ObservableCollection<PropertyNode>(); if (descriptors != null) { var context = TransactionContext.As<ITransactionContext>(); if (context == null) context = DataContext.As<ITransactionContext>(); foreach (var descriptor in descriptors) { if (descriptor.IsBrowsable) { PropertyNode node; if (PropertyFactory != null) { node = PropertyFactory.CreateProperty(instances, descriptor, true, context); } else { node = new PropertyNode(); node.Initialize(instances, descriptor, true); } node.ValueSet += node_ValueSet; node.ValueError += node_ValueError; if (node.Category != null) { bool expansionState; if (m_categoryExpanded.TryGetValue(node.Category, out expansionState)) node.IsExpanded = expansionState; } if (headerPropertyNode == null && descriptor.Attributes[typeof(HeaderPropertyAttribute)] != null) headerPropertyNode = node; else propertyNodes.Add(node); } } } // Listen for expansion state changes so that we can persist through different objects. m_listener = ChangeListener.Create(propertyNodes, "IsExpanded"); m_listener.PropertyChanged += ChildExpandedPropertyChanged; Properties = propertyNodes; HeaderProperty = headerPropertyNode; }
private PropertyNode _EnsureCollection(string collectionName) { Assert.IsNeitherNullNorEmpty(collectionName); Assert.IsNeitherNullNorEmpty(SchemaStrings.TryGetCollectionNodeName(collectionName)); PropertyNode propNode = _contactTree.Lookup.FindNode(collectionName, NodeTypes.Any); if (null != propNode) { return propNode; } // All collection nodes are children of the root contact node. XmlElement collectionElement = _namespaceManager.CreateSchemaElement(collectionName); // Insert the node into the DOM tree. // This is only going to be called when creating an array node // under it, so don't need to set the nil attribute. _document.DocumentElement.AppendChild(collectionElement); // Don't validate, because the empty collection might be illegal. // This should only be called when we're about to add a node, // so the validation will occur in a short while. // Also insert the node into the PropertyNode mirror. // ??? _contactTree.AddXmlNode(collectionElement, _contactTree.ContactRoot); propNode = new PropertyNode(collectionElement, _contactTree.ContactRoot) { Version = 1, IContactName = collectionName }; _contactTree.Lookup.Add(propNode); return propNode; }
private void ParseProperty(StyleNodeContainer styleRootNode, bool parsingKeyframes = false) { StyleToken propertyNodeToken = tokenStream.Current; string propertyName; if (AdvanceIfTokenType(StyleTokenType.Cursor)) { propertyName = propertyNodeToken.value; } else if (AdvanceIfTokenType(StyleTokenType.Run)) { styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Run)); return; } else if (AdvanceIfTokenType(StyleTokenType.Pause)) { styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Pause)); return; } else if (AdvanceIfTokenType(StyleTokenType.Stop)) { styleRootNode.AddChildNode(ParseRunNode(RunCommandType.Enter, RunAction.Stop)); return; } else if (AdvanceIfTokenType(StyleTokenType.BracketOpen)) { if (TryParseCommand(styleRootNode)) { return; } throw new ParseException(tokenStream.Current, "Not sure what you tried here but at this point only [enter] and [exit] run animation would be legal."); } else { propertyName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier); if (propertyName == "material" || propertyName == "Material") { if (tokenStream.Current == StyleTokenType.Colon) { tokenStream.Advance(); string materialName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier); AssertTokenTypeAndAdvance(StyleTokenType.Dot); string materialPropertyName = AssertTokenTypeAndAdvance(StyleTokenType.Identifier); AssertTokenTypeAndAdvance(StyleTokenType.EqualSign); TextUtil.StringBuilder.Clear(); while (tokenStream.HasMoreTokens && tokenStream.Current != StyleTokenType.EndStatement) { TextUtil.StringBuilder.Append(tokenStream.Current.value); tokenStream.Advance(); } tokenStream.Advance(); MaterialPropertyNode materialPropertyNode = new MaterialPropertyNode { materialName = materialName, identifier = materialPropertyName, value = TextUtil.StringBuilder.ToString() }; TextUtil.StringBuilder.Clear(); materialPropertyNode.WithLocation(propertyNodeToken); styleRootNode.AddChildNode(materialPropertyNode); return; } } } AssertTokenTypeAndAdvance(StyleTokenType.EqualSign); PropertyNode propertyNode = StyleASTNodeFactory.PropertyNode(propertyName); propertyNode.WithLocation(propertyNodeToken); while (tokenStream.HasMoreTokens && !AdvanceIfTokenType(StyleTokenType.EndStatement)) { propertyNode.AddChildNode(ParsePropertyValue()); // we just ignore the comma for now AdvanceIfTokenType(StyleTokenType.Comma); } styleRootNode.AddChildNode(propertyNode); }
private PropertyNode _EnsureSimpleCollection(string extensionNamespace, string collectionName) { Assert.IsNeitherNullNorEmpty(extensionNamespace); Assert.IsNeitherNullNorEmpty(collectionName); string icontactPath = "[" + extensionNamespace + "]" + collectionName; PropertyNode propNode = _contactTree.Lookup.FindNode(icontactPath, NodeTypes.Any); if (null != propNode) { return propNode; } // All simple extension collection nodes are children of the root extension node. XmlElement collectionElement = _namespaceManager.CreateExtensionElement(extensionNamespace, collectionName); collectionElement.Attributes.Append(_namespaceManager.CreateNodeTypeAttribute(SchemaStrings.SchemaTypeArrayElement)); _namespaceManager.AddNilAttribute(collectionElement); bool removedExtendedRootNil = false; _SetUnusableOnException( () => { // Adding a child node to extended, ensure it doesn't have the xsi:nil attribute. if (_contactTree.ExtendedRoot.XsiNil) { Assert.AreEqual(0, _contactTree.ExtendedRoot.Children.Count); XmlUtil.RemoveNilAttribute(_contactTree.ExtendedRoot.XmlNode); _contactTree.ExtendedRoot.XsiNil = false; // Need to rollback this action if we fail. removedExtendedRootNil = true; } // Insert the node into the DOM tree. _contactTree.ExtendedRoot.XmlNode.AppendChild(collectionElement); // Also insert the node into the PropertyNode mirror. propNode = new PropertyNode(collectionElement, _contactTree.ExtendedRoot) { Version = 1, IContactName = icontactPath }; _contactTree.Lookup.Add(propNode); }, () => { // This was an append, so it should be LastChild. XmlNode parentNode = _contactTree.ExtendedRoot.XmlNode; if (parentNode.LastChild == collectionElement) { parentNode.RemoveChild(collectionElement); } // Remove the propNode from the tree. if (null != propNode) { _contactTree.ExtendedRoot.Children.Remove(propNode); _contactTree.Lookup.Remove(propNode); } // If this was the first extended collection being added, might need to add back the Nil attribute. if (removedExtendedRootNil) { _namespaceManager.AddNilAttribute(_contactTree.ExtendedRoot.XmlNode); _contactTree.ExtendedRoot.XsiNil = true; } return true; }); return propNode; }
public void GenerateNodeEntries() { // First build up temporary data structure containing group & title as an array of strings (the last one is the actual title) and associated node type. var nodeEntries = new List <NodeEntry>(); foreach (var type in TypeCache.GetTypesDerivedFrom <AbstractMaterialNode>()) { if ((!type.IsClass || type.IsAbstract) || type == typeof(PropertyNode) || type == typeof(KeywordNode) || type == typeof(SubGraphNode)) { continue; } if (type.GetCustomAttributes(typeof(TitleAttribute), false) is TitleAttribute[] attrs && attrs.Length > 0) { var node = (AbstractMaterialNode)Activator.CreateInstance(type); AddEntries(node, attrs[0].title, nodeEntries); } } foreach (var guid in AssetDatabase.FindAssets(string.Format("t:{0}", typeof(SubGraphAsset)))) { var asset = AssetDatabase.LoadAssetAtPath <SubGraphAsset>(AssetDatabase.GUIDToAssetPath(guid)); var node = new SubGraphNode { asset = asset }; var title = asset.path.Split('/').ToList(); if (asset.descendents.Contains(m_Graph.assetGuid) || asset.assetGuid == m_Graph.assetGuid) { continue; } if (string.IsNullOrEmpty(asset.path)) { AddEntries(node, new string[1] { asset.name }, nodeEntries); } else if (title[0] != k_HiddenFolderName) { title.Add(asset.name); AddEntries(node, title.ToArray(), nodeEntries); } } foreach (var property in m_Graph.properties) { var node = new PropertyNode(); node.owner = m_Graph; node.propertyGuid = property.guid; node.owner = null; AddEntries(node, new[] { "Properties", "Property: " + property.displayName }, nodeEntries); } foreach (var keyword in m_Graph.keywords) { var node = new KeywordNode(); node.owner = m_Graph; node.keywordGuid = keyword.guid; node.owner = null; AddEntries(node, new[] { "Keywords", "Keyword: " + keyword.displayName }, nodeEntries); } // Sort the entries lexicographically by group then title with the requirement that items always comes before sub-groups in the same group. // Example result: // - Art/BlendMode // - Art/Adjustments/ColorBalance // - Art/Adjustments/Contrast nodeEntries.Sort((entry1, entry2) => { for (var i = 0; i < entry1.title.Length; i++) { if (i >= entry2.title.Length) { return(1); } var value = entry1.title[i].CompareTo(entry2.title[i]); if (value != 0) { // Make sure that leaves go before nodes if (entry1.title.Length != entry2.title.Length && (i == entry1.title.Length - 1 || i == entry2.title.Length - 1)) { //once nodes are sorted, sort slot entries by slot order instead of alphebetically var alphaOrder = entry1.title.Length < entry2.title.Length ? -1 : 1; var slotOrder = entry1.compatibleSlotId.CompareTo(entry2.compatibleSlotId); return(alphaOrder.CompareTo(slotOrder)); } return(value); } } return(0); }); currentNodeEntries = nodeEntries; }
// BUGBUG: Need to remove ContentType attribute when deleting binary properties. private bool _DeleteProperty(PropertyNode oldProperty) { Assert.IsNotNull(oldProperty.Parent); // Make a copy to work with. // Since we're setting xsi:nil, don't need to make a deep copy. XmlNode copyNode = oldProperty.XmlNode.CloneNode(false); _namespaceManager.AddNilAttribute(copyNode); _namespaceManager.UpdateVersionAndModificationDate(copyNode); XmlNode originalParentNode = oldProperty.XmlNode.ParentNode; XmlNode originalNode = oldProperty.XmlNode; bool swappedNodes = false; bool swappedProperties = false; PropertyNode copyProperty = null; _SetUnusableOnException( () => { // Modify the DOM tree and validate the new version. If this fails we can still roll back. originalParentNode.ReplaceChild(copyNode, originalNode); swappedNodes = true; _ValidateDom(); copyProperty = oldProperty.CloneForSwap(false, false, copyNode); // Change looks good. Start modifying the rest of the class-level data structures. // Failure here isn't handled. We'll instead keep the invalidate flag on the object. copyProperty.Parent.ReplaceChild(copyProperty, oldProperty); swappedProperties = true; _contactTree.Lookup.Remove(oldProperty, true); _contactTree.Lookup.Add(copyProperty); }, () => { if (swappedNodes) { originalParentNode.ReplaceChild(originalNode, copyNode); } if (swappedProperties) { Assert.IsNotNull(copyProperty); copyProperty.Parent.ReplaceChild(oldProperty, copyProperty); } _contactTree.Lookup.Remove(copyProperty); foreach (PropertyNode readdProperties in oldProperty) { _contactTree.Lookup.Replace(readdProperties); } return true; }); Assert.Evaluate(() => _document.Validate((sender, e) => Assert.Fail())); _SuperExpensiveDeepValidate(this); return true; }
public List <SearchTreeEntry> CreateSearchTree(SearchWindowContext context) { // First build up temporary data structure containing group & title as an array of strings (the last one is the actual title) and associated node type. var nodeEntries = new List <NodeEntry>(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypesOrNothing()) { if (type.IsClass && !type.IsAbstract && (type.IsSubclassOf(typeof(AbstractMaterialNode))) && type != typeof(PropertyNode) && type != typeof(SubGraphNode)) { var attrs = type.GetCustomAttributes(typeof(TitleAttribute), false) as TitleAttribute[]; if (attrs != null && attrs.Length > 0) { var node = (AbstractMaterialNode)Activator.CreateInstance(type); AddEntries(node, attrs[0].title, nodeEntries); } } } } foreach (var guid in AssetDatabase.FindAssets(string.Format("t:{0}", typeof(SubGraphAsset)))) { var asset = AssetDatabase.LoadAssetAtPath <SubGraphAsset>(AssetDatabase.GUIDToAssetPath(guid)); var node = new SubGraphNode { subGraphAsset = asset }; var title = node.subGraphData.path.Split('/').ToList(); if (node.subGraphData.descendents.Contains(m_Graph.assetGuid) || node.subGraphData.assetGuid == m_Graph.assetGuid) { continue; } if (string.IsNullOrEmpty(node.subGraphData.path)) { AddEntries(node, new string[1] { asset.name }, nodeEntries); } else if (title[0] != k_HiddenFolderName) { title.Add(asset.name); AddEntries(node, title.ToArray(), nodeEntries); } } foreach (var property in m_Graph.properties) { var node = new PropertyNode(); var property1 = property; node.owner = m_Graph; node.propertyGuid = property1.guid; node.owner = null; AddEntries(node, new[] { "Properties", "Property: " + property.displayName }, nodeEntries); } // Sort the entries lexicographically by group then title with the requirement that items always comes before sub-groups in the same group. // Example result: // - Art/BlendMode // - Art/Adjustments/ColorBalance // - Art/Adjustments/Contrast nodeEntries.Sort((entry1, entry2) => { for (var i = 0; i < entry1.title.Length; i++) { if (i >= entry2.title.Length) { return(1); } var value = entry1.title[i].CompareTo(entry2.title[i]); if (value != 0) { // Make sure that leaves go before nodes if (entry1.title.Length != entry2.title.Length && (i == entry1.title.Length - 1 || i == entry2.title.Length - 1)) { return(entry1.title.Length < entry2.title.Length ? -1 : 1); } return(value); } } return(0); }); //* Build up the data structure needed by SearchWindow. // `groups` contains the current group path we're in. var groups = new List <string>(); // First item in the tree is the title of the window. var tree = new List <SearchTreeEntry> { new SearchTreeGroupEntry(new GUIContent("Create Node"), 0), }; foreach (var nodeEntry in nodeEntries) { // `createIndex` represents from where we should add new group entries from the current entry's group path. var createIndex = int.MaxValue; // Compare the group path of the current entry to the current group path. for (var i = 0; i < nodeEntry.title.Length - 1; i++) { var group = nodeEntry.title[i]; if (i >= groups.Count) { // The current group path matches a prefix of the current entry's group path, so we add the // rest of the group path from the currrent entry. createIndex = i; break; } if (groups[i] != group) { // A prefix of the current group path matches a prefix of the current entry's group path, // so we remove everyfrom from the point where it doesn't match anymore, and then add the rest // of the group path from the current entry. groups.RemoveRange(i, groups.Count - i); createIndex = i; break; } } // Create new group entries as needed. // If we don't need to modify the group path, `createIndex` will be `int.MaxValue` and thus the loop won't run. for (var i = createIndex; i < nodeEntry.title.Length - 1; i++) { var group = nodeEntry.title[i]; groups.Add(group); tree.Add(new SearchTreeGroupEntry(new GUIContent(group)) { level = i + 1 }); } // Finally, add the actual entry. tree.Add(new SearchTreeEntry(new GUIContent(nodeEntry.title.Last(), m_Icon)) { level = nodeEntry.title.Length, userData = nodeEntry }); } return(tree); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Constructor. </summary> /// /// <param name="parentNode"> The parent node. </param> public ModelExtractorSettings(PropertyNode parentNode) : base(parentNode) { Extractor = (ExtractorPathSettings)SettingsManager.GetSettings("OpenSauceIDE.ModelExtractor.Extractor", typeof(ExtractorPathSettings)); Collada = (ExtractorColladaSettings)SettingsManager.GetSettings("OpenSauceIDE.ModelExtractor.Collada", typeof(ExtractorColladaSettings)); }
/// Constructor public FCSComponent(FlightControlSystem fcsParent, XmlElement element) { input = output = delay_time = 0.0; delay = index = 0; ClipMin = ClipMax = new RealValue(0.0); clip = cyclic_clip = false; dt = fcs.GetChannelDeltaT(); propertyManager = fcs.GetPropertyManager(); if (element.LocalName.Equals("lag_filter")) { compType = "LAG_FILTER"; } else if (element.LocalName.Equals("lead_lag_filter")) { compType = "LEAD_LAG_FILTER"; } else if (element.LocalName.Equals("washout_filter")) { compType = "WASHOUT_FILTER"; } else if (element.LocalName.Equals("second_order_filter")) { compType = "SECOND_ORDER_FILTER"; } else if (element.LocalName.Equals("integrator")) { compType = "INTEGRATOR"; } else if (element.LocalName.Equals("summer")) { compType = "SUMMER"; } else if (element.LocalName.Equals("pure_gain")) { compType = "PURE_GAIN"; } else if (element.LocalName.Equals("scheduled_gain")) { compType = "SCHEDULED_GAIN"; } else if (element.LocalName.Equals("aerosurface_scale")) { compType = "AEROSURFACE_SCALE"; } else if (element.LocalName.Equals("switch")) { compType = "SWITCH"; } else if (element.LocalName.Equals("kinematic")) { compType = "KINEMATIC"; } else if (element.LocalName.Equals("deadband")) { compType = "DEADBAND"; } else if (element.LocalName.Equals("fcs_function")) { compType = "FCS_FUNCTION"; } else if (element.LocalName.Equals("pid")) { compType = "PID"; } else if (element.LocalName.Equals("sensor")) { compType = "SENSOR"; } else if (element.LocalName.Equals("accelerometer")) { compType = "ACCELEROMETER"; } else if (element.LocalName.Equals("magnetometer")) { compType = "MAGNETOMETER"; } else if (element.LocalName.Equals("gyro")) { compType = "GYRO"; } else if (element.LocalName.Equals("actuator")) { compType = "ACTUATOR"; } else if (element.LocalName.Equals("waypoint_heading")) { compType = "WAYPOINT_HEADING"; } else if (element.LocalName.Equals("waypoint_distance")) { compType = "WAYPOINT_DISTANCE"; } else if (element.LocalName.Equals("angle")) { compType = "ANGLE"; } else if (element.LocalName.Equals("distributor")) { compType = "DISTRIBUTOR"; } else { // illegal component in this channel compType = "UNKNOWN"; } name = element.GetAttribute("name"); foreach (XmlNode currentNode in element.GetElementsByTagName("init")) { if (currentNode.NodeType == XmlNodeType.Element) { XmlElement init_element = (XmlElement)currentNode; initNodes.Add(new PropertyValue(init_element.InnerText, propertyManager)); } } foreach (XmlNode currentNode in element.GetElementsByTagName("input")) { if (currentNode.NodeType == XmlNodeType.Element) { XmlElement input_element = (XmlElement)currentNode; inputNodes.Add(new PropertyValue(input_element.InnerText, propertyManager)); } } foreach (XmlNode currentNode in element.GetElementsByTagName("output")) { if (currentNode.NodeType == XmlNodeType.Element) { XmlElement out_elem = (XmlElement)currentNode; string output_node_name = out_elem.InnerText; bool node_exists = propertyManager.HasNode(output_node_name); PropertyNode OutputNode = propertyManager.GetNode(output_node_name, true); if (OutputNode == null) { log.Error(" Unable to process property: " + output_node_name); throw new Exception("Invalid output property name in flight control definition"); } outputNodes.Add(OutputNode); // If the node has just been created then it must be initialized to a // sensible value since FGPropertyNode::GetNode() does not take care of // that. If the node was already existing, its current value is kept // unchanged. if (!node_exists) { OutputNode.Set(output); } } } XmlElement delay_elem = element.FindElement("delay"); if (delay_elem != null) { delay_time = delay_elem.GetDataAsNumber(); string delayType = delay_elem.GetAttribute("type"); if (!string.IsNullOrEmpty(delayType)) { if (delayType == "time") { delay = (int)(delay_time / dt); } else if (delayType == "frames") { delay = (int)delay_time; } else { log.Error("Unallowed delay type"); } } else { delay = (int)(delay_time / dt); } output_array.Resize(delay); for (int i = 0; i < delay; i++) { output_array[i] = 0.0; } } XmlElement clip_el = element.FindElement("clipto"); if (clip_el != null) { XmlElement el = clip_el.FindElement("min"); if (el == null) { log.Error("Element <min> is missing, <clipto> is ignored."); return; } ClipMin = new ParameterValue(el, propertyManager); el = clip_el.FindElement("max"); if (el == null) { log.Error("Element <max> is missing, <clipto> is ignored."); ClipMin = null; return; } ClipMax = new ParameterValue(el, propertyManager); if (clip_el.GetAttribute("type") == "cyclic") { cyclic_clip = true; } clip = true; } Debug(0); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Constructor. </summary> /// /// <param name="parentNode"> The parent node. </param> public ExtractorColladaSettings(PropertyNode parentNode) : base(parentNode) { if (!parentNode.Has("Overwrite")) { Overwrite = false; } if (!parentNode.Has("BitmapFormat")) { BitmapFormat = AssetFormat.tga; } }
/// <summary> /// Visits a single <see cref="PropertyNode"/> and produces a value of type <typeparamref name="TResult"/>. /// </summary> /// <param name="node">The node to visit.</param> /// <returns>The result of visitng the node.</returns> protected internal abstract TResult VisitProperty(PropertyNode node);
/// <summary> /// Gets the DataTemplate resource for SliderValueEditor</summary> /// <param name="node">PropertyNode (unused)</param> /// <returns>DataTemplate resource for SliderValueEditor</returns> public override DataTemplate GetTemplate(PropertyNode node) { return Application.Current.FindResource(TemplateKey) as DataTemplate; }
public PropertyValue(PropertyNode n) { node = n; doubleDelegate = n.GetDoubleDelegate; }
private void DestroyPropertyNode(PropertyNode node) { node.ValueSet -= node_ValueSet; node.ValueError -= node_ValueError; node.Dispose(); }
public void ToSubGraph() { var path = EditorUtility.SaveFilePanelInProject("Save subgraph", "New SubGraph", ShaderSubGraphImporter.Extension, ""); path = path.Replace(Application.dataPath, "Assets"); if (path.Length == 0) { return; } graphObject.RegisterCompleteObjectUndo("Convert To Subgraph"); var graphView = graphEditorView.graphView; var nodes = graphView.selection.OfType <MaterialNodeView>().Where(x => !(x.node is PropertyNode)).Select(x => x.node as INode).ToArray(); var bounds = Rect.MinMaxRect(float.PositiveInfinity, float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity); foreach (var node in nodes) { var center = node.drawState.position.center; bounds = Rect.MinMaxRect( Mathf.Min(bounds.xMin, center.x), Mathf.Min(bounds.yMin, center.y), Mathf.Max(bounds.xMax, center.x), Mathf.Max(bounds.yMax, center.y)); } var middle = bounds.center; bounds.center = Vector2.zero; // Collect the property nodes and get the corresponding properties var propertyNodeGuids = graphView.selection.OfType <MaterialNodeView>().Where(x => (x.node is PropertyNode)).Select(x => ((PropertyNode)x.node).propertyGuid); var metaProperties = graphView.graph.properties.Where(x => propertyNodeGuids.Contains(x.guid)); var copyPasteGraph = new CopyPasteGraph( graphView.graph.guid, graphView.selection.OfType <MaterialNodeView>().Where(x => !(x.node is PropertyNode)).Select(x => x.node as INode), graphView.selection.OfType <Edge>().Select(x => x.userData as IEdge), graphView.selection.OfType <BlackboardField>().Select(x => x.userData as IShaderProperty), metaProperties); var deserialized = CopyPasteGraph.FromJson(JsonUtility.ToJson(copyPasteGraph, false)); if (deserialized == null) { return; } var subGraph = new SubGraph(); var subGraphOutputNode = new SubGraphOutputNode(); { var drawState = subGraphOutputNode.drawState; drawState.position = new Rect(new Vector2(bounds.xMax + 200f, 0f), drawState.position.size); subGraphOutputNode.drawState = drawState; } subGraph.AddNode(subGraphOutputNode); var nodeGuidMap = new Dictionary <Guid, Guid>(); foreach (var node in deserialized.GetNodes <INode>()) { var oldGuid = node.guid; var newGuid = node.RewriteGuid(); nodeGuidMap[oldGuid] = newGuid; var drawState = node.drawState; drawState.position = new Rect(drawState.position.position - middle, drawState.position.size); node.drawState = drawState; subGraph.AddNode(node); } // figure out what needs remapping var externalOutputSlots = new List <IEdge>(); var externalInputSlots = new List <IEdge>(); foreach (var edge in deserialized.edges) { var outputSlot = edge.outputSlot; var inputSlot = edge.inputSlot; Guid remappedOutputNodeGuid; Guid remappedInputNodeGuid; var outputSlotExistsInSubgraph = nodeGuidMap.TryGetValue(outputSlot.nodeGuid, out remappedOutputNodeGuid); var inputSlotExistsInSubgraph = nodeGuidMap.TryGetValue(inputSlot.nodeGuid, out remappedInputNodeGuid); // pasting nice internal links! if (outputSlotExistsInSubgraph && inputSlotExistsInSubgraph) { var outputSlotRef = new SlotReference(remappedOutputNodeGuid, outputSlot.slotId); var inputSlotRef = new SlotReference(remappedInputNodeGuid, inputSlot.slotId); subGraph.Connect(outputSlotRef, inputSlotRef); } // one edge needs to go to outside world else if (outputSlotExistsInSubgraph) { externalInputSlots.Add(edge); } else if (inputSlotExistsInSubgraph) { externalOutputSlots.Add(edge); } } // Find the unique edges coming INTO the graph var uniqueIncomingEdges = externalOutputSlots.GroupBy( edge => edge.outputSlot, edge => edge, (key, edges) => new { slotRef = key, edges = edges.ToList() }); var externalInputNeedingConnection = new List <KeyValuePair <IEdge, IShaderProperty> >(); foreach (var group in uniqueIncomingEdges) { var sr = group.slotRef; var fromNode = graphObject.graph.GetNodeFromGuid(sr.nodeGuid); var fromSlot = fromNode.FindOutputSlot <MaterialSlot>(sr.slotId); IShaderProperty prop; switch (fromSlot.concreteValueType) { case ConcreteSlotValueType.Texture2D: prop = new TextureShaderProperty(); break; case ConcreteSlotValueType.Texture2DArray: prop = new Texture2DArrayShaderProperty(); break; case ConcreteSlotValueType.Texture3D: prop = new Texture3DShaderProperty(); break; case ConcreteSlotValueType.Cubemap: prop = new CubemapShaderProperty(); break; case ConcreteSlotValueType.Vector4: prop = new Vector4ShaderProperty(); break; case ConcreteSlotValueType.Vector3: prop = new Vector3ShaderProperty(); break; case ConcreteSlotValueType.Vector2: prop = new Vector2ShaderProperty(); break; case ConcreteSlotValueType.Vector1: prop = new Vector1ShaderProperty(); break; case ConcreteSlotValueType.Boolean: prop = new BooleanShaderProperty(); break; default: throw new ArgumentOutOfRangeException(); } if (prop != null) { var materialGraph = (AbstractMaterialGraph)graphObject.graph; var fromPropertyNode = fromNode as PropertyNode; var fromProperty = fromPropertyNode != null?materialGraph.properties.FirstOrDefault(p => p.guid == fromPropertyNode.propertyGuid) : null; prop.displayName = fromProperty != null ? fromProperty.displayName : fromNode.name; subGraph.AddShaderProperty(prop); var propNode = new PropertyNode(); { var drawState = propNode.drawState; drawState.position = new Rect(new Vector2(bounds.xMin - 300f, 0f), drawState.position.size); propNode.drawState = drawState; } subGraph.AddNode(propNode); propNode.propertyGuid = prop.guid; foreach (var edge in group.edges) { subGraph.Connect( new SlotReference(propNode.guid, PropertyNode.OutputSlotId), new SlotReference(nodeGuidMap[edge.inputSlot.nodeGuid], edge.inputSlot.slotId)); externalInputNeedingConnection.Add(new KeyValuePair <IEdge, IShaderProperty>(edge, prop)); } } } var uniqueOutgoingEdges = externalInputSlots.GroupBy( edge => edge.inputSlot, edge => edge, (key, edges) => new { slot = key, edges = edges.ToList() }); var externalOutputsNeedingConnection = new List <KeyValuePair <IEdge, IEdge> >(); foreach (var group in uniqueOutgoingEdges) { var outputNode = subGraph.outputNode; var slotId = outputNode.AddSlot(); var inputSlotRef = new SlotReference(outputNode.guid, slotId); foreach (var edge in group.edges) { var newEdge = subGraph.Connect(new SlotReference(nodeGuidMap[edge.outputSlot.nodeGuid], edge.outputSlot.slotId), inputSlotRef); externalOutputsNeedingConnection.Add(new KeyValuePair <IEdge, IEdge>(edge, newEdge)); } } File.WriteAllText(path, EditorJsonUtility.ToJson(subGraph)); AssetDatabase.ImportAsset(path); var loadedSubGraph = AssetDatabase.LoadAssetAtPath(path, typeof(MaterialSubGraphAsset)) as MaterialSubGraphAsset; if (loadedSubGraph == null) { return; } var subGraphNode = new SubGraphNode(); var ds = subGraphNode.drawState; ds.position = new Rect(middle - new Vector2(100f, 150f), Vector2.zero); subGraphNode.drawState = ds; graphObject.graph.AddNode(subGraphNode); subGraphNode.subGraphAsset = loadedSubGraph; foreach (var edgeMap in externalInputNeedingConnection) { graphObject.graph.Connect(edgeMap.Key.outputSlot, new SlotReference(subGraphNode.guid, edgeMap.Value.guid.GetHashCode())); } foreach (var edgeMap in externalOutputsNeedingConnection) { graphObject.graph.Connect(new SlotReference(subGraphNode.guid, edgeMap.Value.inputSlot.slotId), edgeMap.Key.inputSlot); } graphObject.graph.RemoveElements( graphView.selection.OfType <MaterialNodeView>().Select(x => x.node as INode), Enumerable.Empty <IEdge>()); graphObject.graph.ValidateGraph(); }
/// <summary> /// Gets the DataTemplate resource for MultiLineTextValueEditor</summary> /// <param name="node">PropertyNode (unused)</param> /// <param name="container">DependencyObject container of TextBox</param> /// <returns>DataTemplate resource for MultiLineTextValueEditor</returns> public override DataTemplate GetTemplate(PropertyNode node, DependencyObject container) { return FindResource<DataTemplate>(TemplateKey, container); }
private PropertyGroup FindParentPropertyGroup(PropertyNode node) { return(_knownGroups.FirstOrDefault(x => x.Children.Contains(node))); }