Ejemplo n.º 1
0
        public static void PasteOutside(bool reposition, Vector2?position = null)
        {
            if (!canPasteOutside)
            {
                throw new InvalidOperationException();
            }

            UndoUtility.RecordEditedObject("Paste Graph Elements");

            var pastedElements = GetPasteGroup();

            // Assign new GUIDs

            foreach (var pastedElement in pastedElements)
            {
                pastedElement.guid = Guid.NewGuid();
            }

            // Add elements to graph and selection

            selection.Clear();

            foreach (var pastedElement in pastedElements)
            {
                if (!pastedElement.HandleDependencies())
                {
                    continue;
                }

                graph.elements.Add(pastedElement);

                selection.Add(pastedElement);
            }

            canvas.Cache();

            foreach (var pastedElement in pastedElements)
            {
                var pastedWidget = canvas.Widget(pastedElement);
                pastedWidget.BringToFront();
            }

            var pastedWidgets = pastedElements.Select(e => canvas.Widget(e)).ToList();

            // Recenter elements in graph view

            if (reposition)
            {
                var area = GraphGUI.CalculateArea(pastedWidgets.Where(widget => widget.canDrag));

                Vector2 delta;

                if (position.HasValue)
                {
                    delta = position.Value - area.position;
                }
                else
                {
                    delta = graph.pan - area.center;
                }

                foreach (var pastedWidget in pastedWidgets)
                {
                    if (pastedWidget.canDrag)
                    {
                        pastedWidget.position = new Rect(pastedWidget.position.position + delta, pastedWidget.position.size).PixelPerfect();
                        pastedWidget.Reposition();
                        pastedWidget.CachePositionFirstPass();
                        pastedWidget.CachePosition();
                    }
                }
            }

            // Space out overlapping elements

            foreach (var pastedWidget in pastedWidgets)
            {
                if (pastedWidget.canDrag)
                {
                    var distanciation = 20;
                    var timeout       = 100;
                    var timeoutIndex  = 0;

                    while (GraphGUI.PositionOverlaps(canvas, pastedWidget, 5))
                    {
                        // Space the widget out
                        pastedWidget.position = new Rect(pastedWidget.position.position + new Vector2(distanciation, distanciation), pastedWidget.position.size).PixelPerfect();

                        // Calculate the resulting position immediately
                        pastedWidget.CachePositionFirstPass();
                        pastedWidget.CachePosition();

                        // Mark it as invalid still so dependencies like ports will be recached
                        pastedWidget.Reposition();

                        // Failsafe to keep the editor from freezing
                        if (++timeoutIndex > timeout)
                        {
                            Debug.LogWarning($"Failed to space out pasted element: {pastedWidget.element}");
                            break;
                        }
                    }
                }
            }

            canvas.Cache();

            GUI.changed = true;

            e?.TryUse();
        }