internal static void AddCustomInterpolatorProperties(VisualElement parentElement, BlockNode node, Action setNodesAsDirtyCallback, Action updateNodeViewsCallback) { if (!node.isCustomBlock) { return; } TextField textField = null; { textField = new TextField { value = node.customName, multiline = false }; var propertyRow = new PropertyRow(new Label("Name")); propertyRow.Add(textField, (field) => { field.RegisterCallback <FocusOutEvent>(evt => { if (field.value.Equals(node.customName)) { return; } HashSet <string> usedNames = new HashSet <string>(); foreach (var other in node.contextData.blocks) { if (other != node) { usedNames.Add(other.value.descriptor.displayName); } } setNodesAsDirtyCallback?.Invoke(); node.owner.owner.RegisterCompleteObjectUndo("Change Block Name"); field.value = node.customName = GraphUtil.SanitizeName(usedNames, "{0}_{1}", NodeUtils.ConvertToValidHLSLIdentifier(field.value)); updateNodeViewsCallback?.Invoke(); node.Dirty(ModificationScope.Node); node.owner?.ValidateGraph(); }); }); parentElement.Add(propertyRow); } EnumField typeField = null; { typeField = new EnumField(node.customWidth); var propertyRow = new PropertyRow(new Label("Type")); propertyRow.Add(typeField, (field) => { field.RegisterValueChangedCallback(evt => { if (evt.newValue.Equals(node.customWidth)) { return; } setNodesAsDirtyCallback?.Invoke(); node.owner.owner.RegisterCompleteObjectUndo("Change Block Type"); node.customWidth = (BlockNode.CustomBlockType)evt.newValue; updateNodeViewsCallback?.Invoke(); node.Dirty(ModificationScope.Topological); node.owner?.ValidateGraph(); }); }); parentElement.Add(propertyRow); } }