Exemplo n.º 1
0
        /// <summary>
        /// Make sure our list of PortViews and editables sync up with our NodePorts
        /// </summary>
        protected void UpdatePorts()
        {
            foreach (var port in target.ports)
            {
                if (port.isInput)
                {
                    AddInputPort(port);
                }
                else
                {
                    AddOutputPort(port);
                }
            }

            var reflectionData = NodeReflection.GetNodeType(target.GetType());

            if (reflectionData != null)
            {
                foreach (var editable in reflectionData.editables)
                {
                    AddEditableField(m_SerializedNode.FindPropertyRelative(editable.fieldName));
                }
            }

            // Toggle visibility of the extension container
            RefreshExpandedState();

            // Update state classes
            EnableInClassList("hasInputs", inputs.Count > 0);
            EnableInClassList("hasOutputs", outputs.Count > 0);
        }
Exemplo n.º 2
0
        internal void Initialize(Node node, CanvasView canvas, EdgeConnectorListener connectorListener)
        {
            viewDataKey       = node.ID;
            Target            = node;
            Canvas            = canvas;
            ReflectionData    = NodeReflection.GetNodeType(node.GetType());
            ConnectorListener = connectorListener;

            styleSheets.Add(Resources.Load <StyleSheet>("BlueGraphEditor/NodeView"));
            AddToClassList("nodeView");

            // Add a class name matching the node's name (e.g. `.node-My-Branch`)
            var ussSafeName = Regex.Replace(Target.Name, @"[^a-zA-Z0-9]+", "-").Trim('-');

            AddToClassList($"node-{ussSafeName}");

            var errorContainer = new VisualElement {
                name = "error"
            };

            errorContainer.Add(new VisualElement {
                name = "error-icon"
            });

            errorMessage = new Label {
                name = "error-label"
            };
            errorContainer.Add(errorMessage);

            Insert(0, errorContainer);

            SetPosition(new Rect(node.Position, Vector2.one));
            title = node.Name;

            if (!ReflectionData.Deletable)
            {
                capabilities &= ~Capabilities.Deletable;
            }
            if (!ReflectionData.Moveable)
            {
                capabilities &= ~Capabilities.Movable;
            }

            // Custom OnDestroy() handler via https://forum.unity.com/threads/request-for-visualelement-ondestroy-or-onremoved-event.718814/
            RegisterCallback <DetachFromPanelEvent>((e) => Destroy());
            RegisterCallback <TooltipEvent>(OnTooltip);

            node.OnErrorEvent    += RefreshErrorState;
            node.OnValidateEvent += OnValidate;

            ReloadPorts();
            ReloadEditables();
            RefreshErrorState();

            OnInitialize();
        }
Exemplo n.º 3
0
        protected void ReloadEditables()
        {
            var reflectionData = NodeReflection.GetNodeType(Target.GetType());

            if (reflectionData != null)
            {
                foreach (var editable in reflectionData.Editables)
                {
                    AddEditableField(editable);
                }
            }

            RefreshExpandedState();
        }
Exemplo n.º 4
0
        protected void OnTooltip(TooltipEvent evt)
        {
            // TODO: Better implementation that can be styled
            if (evt.target == titleContainer.Q("title-label"))
            {
                var typeData = NodeReflection.GetNodeType(Target.GetType());
                evt.tooltip = typeData?.Help;

                // Float the tooltip above the node title bar
                var bound = titleContainer.worldBound;
                bound.x       = 0;
                bound.y       = 0;
                bound.height *= -1;

                evt.rect = titleContainer.LocalToWorld(bound);
            }
        }
Exemplo n.º 5
0
        protected virtual void AddInputPort(Port port)
        {
            var view = PortView.Create(port, ConnectorListener);

            // If we're exposing a control element via reflection: include it in the view
            var reflection = NodeReflection.GetNodeType(Target.GetType());
            var element    = reflection.GetPortByName(port.Name)?.GetControlElement(this);

            if (element != null)
            {
                var container = new VisualElement();
                container.AddToClassList("property-field-container");
                container.Add(element);

                view.SetEditorField(container);
            }

            Inputs.Add(view);
            inputContainer.Add(view);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Deserialize a string back into a CopyPasteGraph.
        ///
        /// If <c>includeTags</c> are empty, no filtering will be done. Otherwise,
        /// only nodes with an intersection to one or more tags will be kept.
        /// </summary>
        public static CopyPasteGraph Deserialize(string data, IEnumerable <string> includeTags)
        {
            var graph = CreateInstance <CopyPasteGraph>();

            JsonUtility.FromJsonOverwrite(data, graph);

            // Remove nodes that aren't on the allow list for tags
            var allowedAllNodes = true;

            if (includeTags.Count() > 0)
            {
                graph.Nodes = graph.Nodes.FindAll((node) => {
                    var reflectedNode = NodeReflection.GetNodeType(node.GetType());
                    var allowed       = includeTags.Intersect(reflectedNode.Tags).Count() > 0;
                    allowedAllNodes   = allowedAllNodes && allowed;

                    return(allowed);
                });
            }

            // If we're excluding any from the paste content, notify the user.
            if (!allowedAllNodes)
            {
                Debug.LogWarning("Could not paste one or more nodes - not allowed by the target graph");
            }

            // Generate new unique IDs for each node in the list
            // in case we're copy+pasting back onto the same graph
            var idMap = new Dictionary <string, string>();

            foreach (var node in graph.Nodes)
            {
                var newId = Guid.NewGuid().ToString();
                idMap[node.ID] = newId;
                node.ID        = newId;
            }

            // Remap connections to new node IDs and drop any connections
            // that were to nodes outside of the subset of pasted nodes
            foreach (var node in graph.Nodes)
            {
                foreach (var port in node.Ports.Values)
                {
                    var edges = new List <Connection>(port.Connections);
                    port.Connections.Clear();

                    // Only re-add connections that are in the new pasted subset
                    foreach (var edge in edges)
                    {
                        if (idMap.ContainsKey(edge.NodeID))
                        {
                            port.Connections.Add(new Connection
                            {
                                NodeID   = idMap[edge.NodeID],
                                PortName = edge.PortName
                            });
                        }
                    }
                }
            }

            return(graph);
        }