Esempio n. 1
0
 internal ZoomEventArgs(Point2D offset, double focusWidth, double focusHeight)
 {
     this.Offset = offset;
     this.FocusWidth = focusWidth;
     this.FocusHeight = focusHeight;
     this.Modes = ZoomModes.ByFitView;
 }
Esempio n. 2
0
 internal ZoomEventArgs(Point2D offset, double focusWidth, double focusHeight, double zoom)
 {
     this.Offset = offset;
     this.FocusWidth = focusWidth;
     this.FocusHeight = focusHeight;
     this.Zoom = zoom;
     this.Modes = ZoomModes.ByFitView | ZoomModes.ByFactor;
 }
Esempio n. 3
0
		public Rect2D (Point2D point1, Point2D point2)
		{
			if (point1.X < point2.X) {
				x = point1.X;
				width = point2.X - point1.X;
			}
			else {
				x = point2.X;
				width = point1.X - point2.X;
			}

			if (point1.Y < point2.Y) {
				y = point1.Y;
				height = point2.Y - point1.Y;
			}
			else {
				y = point2.Y;
				height = point1.Y - point2.Y;
			}
		}
Esempio n. 4
0
        /// <summary>
        ///     Paste ISelectable objects from the clipboard to the workspace
        /// so that the nodes appear in their original location with a slight offset
        /// </summary>
        public void Paste()
        {
            var locatableModels = ClipBoard.Where(model => model is NoteModel || model is NodeModel);
            var x = locatableModels.Min(m => m.X);
            var y = locatableModels.Min(m => m.Y);
            var targetPoint = new Point2D(x, y);

            Paste(targetPoint);
        }
Esempio n. 5
0
        private void OnWorkspaceDrop(object sender, DragEventArgs e)
        {
            var mousePosition = e.GetPosition(WorkspaceElements);
            var pointObj = e.Data.GetData(typeof(Point2D));
            if (pointObj is Point2D)
            {
                var offset = (Point2D)pointObj;
                // compute a point where (minX, minY) will be pasted -
                // location of selection top left corner
                var targetX = mousePosition.X - offset.X;
                var targetY = mousePosition.Y - offset.Y;
                var targetPoint = new Point2D(targetX, targetY);

                ViewModel.PasteSelection(targetPoint);

                return;
            }

            var nodeInfo = e.Data.GetData(typeof(DragDropNodeSearchElementInfo)) as DragDropNodeSearchElementInfo;
            if (nodeInfo == null)
                return;

            var nodeModel = nodeInfo.SearchElement.CreateNode();
            ViewModel.DynamoViewModel.ExecuteCommand(new DynamoModel.CreateNodeCommand(
                nodeModel, mousePosition.X, mousePosition.Y, false, true));
        }
Esempio n. 6
0
        void vm_ZoomToFitView(object sender, EventArgs e)
        {
            ZoomEventArgs zoomArgs = (e as ZoomEventArgs);

            double viewportPadding = 30;
            double fitWidth = outerCanvas.ActualWidth - 2 * viewportPadding;
            double fitHeight = outerCanvas.ActualHeight - 2 * viewportPadding;

            // Find the zoom required for fitview
            double scaleRequired = 1; // 100% zoom
            if (zoomArgs.hasZoom()) // FitView
                scaleRequired = zoomArgs.Zoom;
            else
            {
                double scaleX = fitWidth / zoomArgs.FocusWidth;
                double scaleY = fitHeight / zoomArgs.FocusHeight;
                scaleRequired = scaleX > scaleY ? scaleY : scaleX; // get least zoom required
            }

            // Limit Zoom
            if (scaleRequired > WorkspaceModel.ZOOM_MAXIMUM)
                scaleRequired = WorkspaceModel.ZOOM_MAXIMUM;
            else if (scaleRequired < WorkspaceModel.ZOOM_MINIMUM)
                scaleRequired = WorkspaceModel.ZOOM_MINIMUM;

            // Center position
            double centerOffsetX = viewportPadding + (fitWidth - (zoomArgs.FocusWidth * scaleRequired)) / 2;
            double centerOffsetY = viewportPadding + (fitHeight - (zoomArgs.FocusHeight * scaleRequired)) / 2;

            var resultOffset = new Point2D();
            resultOffset.X = -(zoomArgs.Offset.X * scaleRequired) + centerOffsetX;
            resultOffset.Y = -(zoomArgs.Offset.Y * scaleRequired) + centerOffsetY;

            // Apply on model
            ViewModel.Model.Zoom = scaleRequired;
            ViewModel.Model.X = resultOffset.X;
            ViewModel.Model.Y = resultOffset.Y;

            vm_CurrentOffsetChanged(this, new PointEventArgs(resultOffset));
            vm_ZoomChanged(this, new ZoomEventArgs(scaleRequired));
        }
Esempio n. 7
0
        void vm_ZoomAtViewportCenter(object sender, EventArgs e)
        {
            double zoom = AdjustZoomForCurrentZoomAmount((e as ZoomEventArgs).Zoom);

            // Limit Zoom
            double resultZoom = ViewModel.Model.Zoom + zoom;
            if (resultZoom < WorkspaceModel.ZOOM_MINIMUM)
                resultZoom = WorkspaceModel.ZOOM_MINIMUM;
            else if (resultZoom > WorkspaceModel.ZOOM_MAXIMUM)
                resultZoom = WorkspaceModel.ZOOM_MAXIMUM;

            // Get Viewpoint Center point
            var centerPoint = new Point2D();
            centerPoint.X = outerCanvas.ActualWidth / 2;
            centerPoint.Y = outerCanvas.ActualHeight / 2;

            // Get relative point of ZoomBorder child in relates to viewpoint center point
            var relativePoint = new Point2D();
            relativePoint.X = (centerPoint.X - ViewModel.Model.X) / ViewModel.Model.Zoom;
            relativePoint.Y = (centerPoint.Y - ViewModel.Model.Y) / ViewModel.Model.Zoom;

            ZoomAtViewportPoint(zoom, relativePoint);
        }
Esempio n. 8
0
        public void TestDraggedNode()
        {
            var addNode = new DSFunction(ViewModel.Model.LibraryServices.GetFunctionDescriptor("+")) { X = 16, Y = 32 };
            ViewModel.Model.CurrentWorkspace.AddNode(addNode, false);
            NodeModel locatable = ViewModel.Model.CurrentWorkspace.Nodes[0];

            var startPoint = new Point2D(8, 64);
            var dn = new WorkspaceViewModel.DraggedNode(locatable, startPoint);

            // Initial node position.
            Assert.AreEqual(16, locatable.X);
            Assert.AreEqual(32, locatable.Y);

            // Move the mouse cursor to move node.
            dn.Update(new Point2D(-16, 72));
            Assert.AreEqual(-8, locatable.X);
            Assert.AreEqual(40, locatable.Y);
        }
Esempio n. 9
0
        /// <summary>
        ///     Paste ISelectable objects from the clipboard to the workspace 
        /// so that the nodes appear in their original location with a slight offset
        /// </summary>
        public void Paste()
        {
            // Provide a small offset when pasting so duplicate pastes aren't directly on top of each other
            CurrentWorkspace.IncrementPasteOffset();

            var locatableModels = ClipBoard.Where(model => model is NoteModel || model is NodeModel);
            var orderedItems = locatableModels.OrderBy(item => item.CenterX + item.CenterY);

            // Search for the rightmost item. It's item with the biggest X, Y coordinates of center.
            var rightMostItem = orderedItems.Last();

            // Search for the leftmost item. It's item with the smallest X, Y coordinates of center.
            var leftMostItem = orderedItems.First();

            // Compute shift so that left most item will appear at right most item place with offset.
            var shiftX = rightMostItem.X + rightMostItem.Width + CurrentWorkspace.CurrentPasteOffset - leftMostItem.X;
            var shiftY = rightMostItem.Y + CurrentWorkspace.CurrentPasteOffset - leftMostItem.Y;


            var x = shiftX + locatableModels.Min(m => m.X);
            var y = shiftY + locatableModels.Min(m => m.Y);
            var targetPoint = new Point2D(x, y);
            
            Paste(targetPoint);
        }
Esempio n. 10
0
        public void SetTranslateTransformOrigin(Point2D p)
        {
            var tt = GetTranslateTransform(child);
            tt.X = p.X;
            tt.Y = p.Y;

            var st = GetScaleTransform(child);
            NotifyViewSettingsChanged(tt.X, tt.Y, st.ScaleX);
        }
Esempio n. 11
0
        public void UndoMovingNoteInsideGroup()
        {
            OpenModel(@"UI\NoteInGroupTest.dyn");

            var workspaceVm = ViewModel.CurrentSpaceViewModel;

            // check if note is loaded from the file
            var noteVm = workspaceVm.Notes.First();
            Assert.IsNotNull(noteVm);
            var noteX = noteVm.Left;
            var noteY = noteVm.Top;
            var noteCenterX = noteVm.Model.CenterX;
            var noteCenterY = noteVm.Model.CenterY;

            // check if group is loaded from the file
            var groupVm = workspaceVm.Annotations.First();
            Assert.IsNotNull(groupVm);
            var groupX = groupVm.Left;
            var groupY = groupVm.Top;

            // only note should be selected
            DynamoSelection.Instance.Selection.Add(noteVm.Model);

            var point = new Point2D(noteCenterX, noteCenterY);
            var operation = DynamoModel.DragSelectionCommand.Operation.BeginDrag;
            var command = new DynamoModel.DragSelectionCommand(point, operation);

            ViewModel.ExecuteCommand(command);

            operation = DynamoModel.DragSelectionCommand.Operation.EndDrag;
            point.X += 100;
            point.Y += 100;
            command = new DynamoModel.DragSelectionCommand(point, operation);

            ViewModel.ExecuteCommand(command);

            // Check note and annotation are moved
            Assert.AreNotEqual(groupX, groupVm.Left);
            Assert.AreNotEqual(groupY, groupVm.Top);
            Assert.AreNotEqual(noteX, noteVm.Left);
            Assert.AreNotEqual(noteY, noteVm.Top);

            ViewModel.UndoCommand.Execute(null);

            // Check annotation and note are moved back
            var msgPart = " was not moved back";
            Assert.AreEqual(groupX, groupVm.Left, "Group" + msgPart);
            Assert.AreEqual(groupY, groupVm.Top, "Group" + msgPart);
            Assert.AreEqual(noteX, noteVm.Left, "Note" + msgPart);
            Assert.AreEqual(noteY, noteVm.Top, "Note" + msgPart);
        }
Esempio n. 12
0
 internal ZoomEventArgs(double zoom, Point2D point)
 {
     this.Point = point;
     this.Zoom = zoom;
     this.Modes = ZoomModes.ByPoint | ZoomModes.ByFactor;
 }
Esempio n. 13
0
 internal ZoomEventArgs(Point2D point)
 {
     this.Point = point;
     this.Modes = ZoomModes.ByPoint;
 }
Esempio n. 14
0
 public PointEventArgs(Point2D p)
 {
     Point = p;
 }
Esempio n. 15
0
 public bool Contains(Point2D point)
 {
     return(Contains(point.X, point.Y));
 }
Esempio n. 16
0
 public void SetTranslateTransformOrigin(Point2D p)
 {
     var tt = GetTranslateTransform(child);
     tt.X = p.X;
     tt.Y = p.Y;
 }
        internal void FitViewInternal()
        {
            // Get the offset and focus width & height (zoom if 100%)
            double minX, maxX, minY, maxY;

            // Get the width and height of area to fit
            if (DynamoSelection.Instance.Selection.Count > 0)
            {   // has selection
                minX = GetSelectionMinX();
                maxX = GetSelectionMaxX();
                minY = GetSelectionMinY();
                maxY = GetSelectionMaxY();
            }
            else
            {   
                // no selection, fitview all nodes and notes
                var nodes = _nodes.Select(x => x.NodeModel);
                var notes = _notes.Select(x => x.Model);
                var models = nodes.Concat<ModelBase>(notes);

                if (!models.Any()) return;

                // initialize to the first model (either note or node) on the list 

                var firstModel = models.First();
                minX = firstModel.X;
                maxX = firstModel.X;
                minY = firstModel.Y;
                maxY = firstModel.Y;

                foreach (var model in models)
                {
                    //calculates the min and max positions of both x and y coords of all nodes and notes
                    minX = Math.Min(model.X, minX);
                    maxX = Math.Max(model.X + model.Width, maxX);
                    minY = Math.Min(model.Y, minY);
                    maxY = Math.Max(model.Y + model.Height, maxY);
                }
                
            }

            var offset = new Point2D(minX, minY);
            double focusWidth = maxX - minX;
            double focusHeight = maxY - minY;

            _fitViewActualZoomToggle = !_fitViewActualZoomToggle;
            ZoomEventArgs zoomArgs = _fitViewActualZoomToggle
                ? new ZoomEventArgs(offset, focusWidth, focusHeight)
                : new ZoomEventArgs(offset, focusWidth, focusHeight, 1.0);

            OnRequestZoomToFitView(this, zoomArgs);
        }
Esempio n. 18
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="mouseCursor"></param>
 /// <param name="operation"></param>
 public DragSelectionCommand(Point2D mouseCursor, Operation operation)
 {
     MouseCursor = mouseCursor;
     DragOperation = operation;
 }
Esempio n. 19
0
        internal void UpdateDraggedSelection(Point2D mouseCursor)
        {
            if (draggedNodes.Count <= 0)
            {
                throw new InvalidOperationException(
                    "UpdateDraggedSelection cannot be called now");
            }

            foreach (DraggedNode draggedNode in draggedNodes)
                draggedNode.Update(mouseCursor);
        }
Esempio n. 20
0
        internal void FitViewInternal()
        {
            // Get the offset and focus width & height (zoom if 100%)
            double minX, maxX, minY, maxY;

            // Get the width and height of area to fit
            if (DynamoSelection.Instance.Selection.Count > 0)
            {   // has selection
                minX = GetSelectionMinX();
                maxX = GetSelectionMaxX();
                minY = GetSelectionMinY();
                maxY = GetSelectionMaxY();
            }
            else
            {   // no selection, fitview all nodes
                if (!_nodes.Any()) return;

                List<NodeModel> nodes = _nodes.Select(x => x.NodeModel).Where(x => x != null).ToList();
                minX = nodes.Select(x => x.X).Min();
                maxX = nodes.Select(x => x.X + x.Width).Max();
                minY = nodes.Select(y => y.Y).Min();
                maxY = nodes.Select(y => y.Y + y.Height).Max();
            }

            var offset = new Point2D(minX, minY);
            double focusWidth = maxX - minX;
            double focusHeight = maxY - minY;

            _fitViewActualZoomToggle = !_fitViewActualZoomToggle;
            ZoomEventArgs zoomArgs = _fitViewActualZoomToggle
                ? new ZoomEventArgs(offset, focusWidth, focusHeight)
                : new ZoomEventArgs(offset, focusWidth, focusHeight, 1.0);

            OnRequestZoomToFitView(this, zoomArgs);
        }
Esempio n. 21
0
 internal void EndDragSelection(Point2D mouseCursor)
 {
     UpdateDraggedSelection(mouseCursor); // Final position update.
     draggedNodes.Clear(); // We are no longer dragging anything.
 }
Esempio n. 22
0
        /// <summary>
        /// Drag and drop nodes, notes, annotations and connectors.
        /// </summary>
        /// <param name="mouse">Relative position to WorkspaceElements</param>
        private void DragAndDrop(Point mouse)
        {
            // disable clearing selection while dragged data is being generated
            // new AnnotationViewModel unnecessarily clears selection 
            DynamoSelection.Instance.ClearSelectionDisabled = true;
            var selection = DynamoSelection.Instance.Selection;
            var nodes = selection.OfType<NodeModel>();
            var notes = selection.OfType<NoteModel>();
            var annotations = selection.OfType<AnnotationModel>();

            var connectors = nodes.SelectMany(n =>
                n.OutPorts.SelectMany(port => port.Connectors)
                    .Where(c => c.End != null && c.End.Owner.IsSelected)).Distinct();

            // set list of selected viewmodels
            draggedData = connectors.Select(c => (ViewModelBase)new ConnectorViewModel(ViewModel, c))
                .Concat(notes.Select(n => new NoteViewModel(ViewModel, n)))
                .Concat(annotations.Select(a => new AnnotationViewModel(ViewModel, a)))
                .Concat(nodes.Select(n =>
                {
                    var node = this.ChildrenOfType<NodeView>()
                        .FirstOrDefault(view => view.ViewModel.NodeModel == n);
                    if (node == null) return new NodeViewModel(ViewModel, n);

                    var nodeRect = node.nodeBorder;
                    var size = new Size(nodeRect.ActualWidth, nodeRect.ActualHeight);
                    // set fixed size for dragged nodes, 
                    // so that they will correspond to origin nodes
                    return new NodeViewModel(ViewModel, n, size);
                })).ToList();
            
            var locatableModels = nodes.Concat<ModelBase>(notes);
            var minX = locatableModels.Any() ? locatableModels.Min(mb => mb.X) : 0;
            var minY = locatableModels.Any() ? locatableModels.Min(mb => mb.Y) : 0;
            // compute offset to correctly place selected items right under mouse cursor 
            var mouseOffset = new Point2D(mouse.X - minX, mouse.Y - minY);

            DynamoSelection.Instance.ClearSelectionDisabled = false;
            DragDrop.DoDragDrop(this, mouseOffset, DragDropEffects.Copy);

            // remove dragged selection view 
            if (draggedAdorner != null)
            {
                draggedData = null;
                draggedAdorner.Detach();
                draggedAdorner = null;
            }
        }
Esempio n. 23
0
 internal void PasteSelection(Point2D targetPoint)
 {
     stateMachine.PasteSelection(targetPoint);
 }
Esempio n. 24
0
        private void ZoomAtViewportPoint(double zoom, Point2D relative)
        {
            // Limit zoom
            double resultZoom = ViewModel.Model.Zoom + zoom;
            if (resultZoom < WorkspaceModel.ZOOM_MINIMUM)
                resultZoom = WorkspaceModel.ZOOM_MINIMUM;
            else if (resultZoom > WorkspaceModel.ZOOM_MAXIMUM)
                resultZoom = WorkspaceModel.ZOOM_MAXIMUM;

            double absoluteX, absoluteY;
            absoluteX = relative.X * ViewModel.Model.Zoom + ViewModel.Model.X;
            absoluteY = relative.Y * ViewModel.Model.Zoom + ViewModel.Model.Y;
            var resultOffset = new Point2D();
            resultOffset.X = absoluteX - (relative.X * resultZoom);
            resultOffset.Y = absoluteY - (relative.Y * resultZoom);

            ViewModel.Model.Zoom = resultZoom;
            ViewModel.Model.X = resultOffset.X;
            ViewModel.Model.Y = resultOffset.Y;

            vm_CurrentOffsetChanged(this, new PointEventArgs(resultOffset));
            vm_ZoomChanged(this, new ZoomEventArgs(resultZoom));
        }
Esempio n. 25
0
 /// <summary>
 /// Construct a DraggedNode for a given ILocatable object.
 /// </summary>
 /// <param name="locatable">The ILocatable (usually a node) that is 
 /// associated with this DraggedNode object. During an update, the 
 /// position of ILocatable will be updated based on the specified 
 /// mouse position and the internal delta values.</param>
 /// <param name="mouseCursor">The mouse cursor at the point this 
 /// DraggedNode object is constructed. This is used to determine the 
 /// offset of the ILocatable from the mouse cursor.</param>
 /// <param name="region">The region within which the ILocatable can 
 /// be moved. However, the movement of ILocatable will be limited by 
 /// region and that it cannot be moved beyond the region.</param>
 /// 
 public DraggedNode(ILocatable locatable, Point2D mouseCursor)
 {
     this.locatable = locatable;
     deltaX = mouseCursor.X - locatable.X;
     deltaY = mouseCursor.Y - locatable.Y;
 }
Esempio n. 26
0
        private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            WorkspaceViewModel wvm = (DataContext as WorkspaceViewModel);

            if (this.snappedPort != null)
                wvm.HandlePortClicked(this.snappedPort);
            else
            {
                wvm.HandleLeftButtonDown(workBench, e);
            }

            // if selection is going to be dragged and ctrl is pressed
            if (wvm.IsDragging && Keyboard.Modifiers == ModifierKeys.Control)
            {
                initialMousePosition = e.GetPosition(WorkspaceElements);
                
                // disable clearing selection while dragged data is being generated
                // new AnnotationViewModel unnecessarily clears selection 
                DynamoSelection.Instance.ClearSelectionDisabled = true;
                var selection = DynamoSelection.Instance.Selection;
                var nodes = selection.OfType<NodeModel>();
                var notes = selection.OfType<NoteModel>();
                var annotations = selection.OfType<AnnotationModel>();
                
                var connectors = nodes.SelectMany(n => 
                    n.OutPorts.SelectMany(port => port.Connectors)
                        .Where(c => c.End != null && c.End.Owner.IsSelected)).Distinct();

                // set list of selected viewmodels
                draggedData = connectors.Select(c => (ViewModelBase)new ConnectorViewModel(ViewModel, c))
                    .Concat(notes.Select(n => new NoteViewModel(ViewModel, n)))
                    .Concat(annotations.Select(a => new AnnotationViewModel(ViewModel, a)))
                    .Concat(nodes.Select(n =>
                    {
                        var nodeRect = this.ChildrenOfType<NodeView>()
                            .First(view => view.ViewModel.NodeModel == n).nodeBorder;
                        var size = new Size(nodeRect.ActualWidth, nodeRect.ActualHeight);
                        // set fixed size for dragged nodes, 
                        // so that they will correspond to origin nodes
                        return new NodeViewModel(ViewModel, n, size);
                    })).ToList();
                
                var mouse = e.GetPosition(WorkspaceElements);
                var locatableModels = nodes.Concat<ModelBase>(notes);
                var minX = locatableModels.Any() ? locatableModels.Min(mb => mb.X) : 0;
                var minY = locatableModels.Any() ? locatableModels.Min(mb => mb.Y) : 0;
                // compute offset to correctly place selected items right under mouse cursor 
                var mouseOffset = new Point2D(mouse.X - minX, mouse.Y - minY);

                DynamoSelection.Instance.ClearSelectionDisabled = false;
                DragDrop.DoDragDrop(this, mouseOffset, DragDropEffects.Copy);

                // end dragging operation by setting State from DragSetup to None
                ViewModel.HandleMouseRelease(workBench, e);
                // remove dragged selection view 
                if (draggedAdorner != null)
                {
                    draggedData = null;
                    draggedAdorner.Detach();
                    draggedAdorner = null;
                }
            }

            InCanvasSearchBar.IsOpen = false;
        }
Esempio n. 27
0
 public void Update(Point2D mouseCursor)
 {
     // Make sure the nodes do not go beyond the region.
     double x = mouseCursor.X - deltaX;
     double y = mouseCursor.Y - deltaY;
     locatable.X = x;
     locatable.Y = y;
     locatable.ReportPosition();
 }
Esempio n. 28
0
        internal void Pan(object parameter)
        {
            Debug.WriteLine(string.Format("Offset: {0},{1}, Zoom: {2}", model.CurrentWorkspace.X, model.CurrentWorkspace.Y, model.CurrentWorkspace.Zoom));
            var panType = parameter.ToString();
            double pan = 10;
            var pt = new Point2D(model.CurrentWorkspace.X, model.CurrentWorkspace.Y);

            switch (panType)
            {
                case "Left":
                    pt.X += pan;
                    break;
                case "Right":
                    pt.X -= pan;
                    break;
                case "Up":
                    pt.Y += pan;
                    break;
                case "Down":
                    pt.Y -= pan;
                    break;
            }
            model.CurrentWorkspace.X = pt.X;
            model.CurrentWorkspace.Y = pt.Y;

            CurrentSpaceViewModel.Model.OnCurrentOffsetChanged(this, new PointEventArgs(pt));
            CurrentSpaceViewModel.ResetFitViewToggleCommand.Execute(parameter);
        }
Esempio n. 29
0
            internal void PasteSelection(Point2D targetPoint)
            {
                var model = owningWorkspace.DynamoViewModel.Model;
                var oldClipboardData = model.ClipBoard.ToList();

                model.Copy();
                if (model.ClipBoard.Any())
                {
                    model.Paste(targetPoint, false);
                    owningWorkspace.DynamoViewModel.UndoCommand.RaiseCanExecuteChanged();
                    owningWorkspace.DynamoViewModel.RedoCommand.RaiseCanExecuteChanged();
                }

                model.ClipBoard.Clear();
                model.ClipBoard.AddRange(oldClipboardData);
                SetCurrentState(State.None);
            }
Esempio n. 30
0
        /// <summary>
        ///     Paste ISelectable objects from the clipboard to the workspace at specified point.
        /// </summary>
        /// <param name="targetPoint">Location where data will be pasted</param>
        /// <param name="useOffset">Indicates whether we will use current workspace offset or paste nodes
        /// directly in this point. </param>
        public void Paste(Point2D targetPoint, bool useOffset = true)
        {
            if (useOffset)
            {
                // Provide a small offset when pasting so duplicate pastes aren't directly on top of each other
                CurrentWorkspace.IncrementPasteOffset();
            }

            //clear the selection so we can put the
            //paste contents in
            DynamoSelection.Instance.ClearSelection();

            //make a lookup table to store the guids of the
            //old models and the guids of their pasted versions
            var modelLookup = new Dictionary<Guid, ModelBase>();

            //make a list of all newly created models so that their
            //creations can be recorded in the undo recorder.
            var createdModels = new List<ModelBase>();

            var nodes = ClipBoard.OfType<NodeModel>();
            var connectors = ClipBoard.OfType<ConnectorModel>();
            var notes = ClipBoard.OfType<NoteModel>();
            var annotations = ClipBoard.OfType<AnnotationModel>();

            // Create the new NoteModel's
            var newNoteModels = new List<NoteModel>();
            foreach (var note in notes)
            {
                var noteModel = new NoteModel(note.X, note.Y, note.Text, Guid.NewGuid());
                //Store the old note as Key and newnote as value.
                modelLookup.Add(note.GUID,noteModel);
                newNoteModels.Add(noteModel);
            }

            var xmlDoc = new XmlDocument();

            // Create the new NodeModel's
            var newNodeModels = new List<NodeModel>();
            foreach (var node in nodes)
            {
                NodeModel newNode;

                if (CurrentWorkspace is HomeWorkspaceModel && (node is Symbol || node is Output))
                {
                    var symbol = (node is Symbol
                        ? (node as Symbol).InputSymbol
                        : (node as Output).Symbol);
                    var code = (string.IsNullOrEmpty(symbol) ? "x" : symbol) + ";";
                    newNode = new CodeBlockNodeModel(code, node.X, node.Y, LibraryServices, CurrentWorkspace.ElementResolver);
                }
                else
                {
                    var dynEl = node.Serialize(xmlDoc, SaveContext.Copy);
                    newNode = NodeFactory.CreateNodeFromXml(dynEl, SaveContext.Copy, CurrentWorkspace.ElementResolver);
                }

                var lacing = node.ArgumentLacing.ToString();
                newNode.UpdateValue(new UpdateValueParams("ArgumentLacing", lacing));
                if (!string.IsNullOrEmpty(node.NickName) && !(node is Symbol) && !(node is Output))
                    newNode.NickName = node.NickName;

                newNode.Width = node.Width;
                newNode.Height = node.Height;

                modelLookup.Add(node.GUID, newNode);

                newNodeModels.Add(newNode);
            }

            var newItems = newNodeModels.Concat<ModelBase>(newNoteModels);

            var shiftX = targetPoint.X - newItems.Min(item => item.X);
            var shiftY = targetPoint.Y - newItems.Min(item => item.Y);
            var offset = useOffset ? CurrentWorkspace.CurrentPasteOffset : 0;

            foreach (var model in newItems)
            {
                model.X = model.X + shiftX + offset;
                model.Y = model.Y + shiftY + offset;
            }

            // Add the new NodeModel's to the Workspace
            foreach (var newNode in newNodeModels)
            {
                CurrentWorkspace.AddAndRegisterNode(newNode, false);
                createdModels.Add(newNode);
            }

            // TODO: is this required?
            OnRequestLayoutUpdate(this, EventArgs.Empty);

            // Add the new NoteModel's to the Workspace
            foreach (var newNote in newNoteModels)
            {
                CurrentWorkspace.AddNote(newNote, false);
                createdModels.Add(newNote);
            }

            ModelBase start;
            ModelBase end;
            var newConnectors =
                from c in connectors

                // If the guid is in nodeLookup, then we connect to the new pasted node. Otherwise we
                // re-connect to the original.
                let startNode =
                    modelLookup.TryGetValue(c.Start.Owner.GUID, out start)
                        ? start as NodeModel
                        : CurrentWorkspace.Nodes.FirstOrDefault(x => x.GUID == c.Start.Owner.GUID)
                let endNode =
                    modelLookup.TryGetValue(c.End.Owner.GUID, out end)
                        ? end as NodeModel
                        : CurrentWorkspace.Nodes.FirstOrDefault(x => x.GUID == c.End.Owner.GUID)

                // Don't make a connector if either end is null.
                where startNode != null && endNode != null
                select
                    ConnectorModel.Make(startNode, endNode, c.Start.Index, c.End.Index);

            createdModels.AddRange(newConnectors);

            //Grouping depends on the selected node models.
            //so adding the group after nodes / notes are added to workspace.
            //select only those nodes that are part of a group.
            var newAnnotations = new List<AnnotationModel>();
            foreach (var annotation in annotations)
            {
                var annotationNodeModel = new List<NodeModel>();
                var annotationNoteModel = new List<NoteModel>();
                // some models can be deleted after copying them,
                // so they need to be in pasted annotation as well
                var modelsToRestore = annotation.DeletedModelBases.Intersect(ClipBoard);
                var modelsToAdd = annotation.SelectedModels.Concat(modelsToRestore);
                // checked condition here that supports pasting of multiple groups
                foreach (var models in modelsToAdd)
                {
                    ModelBase mbase;
                    modelLookup.TryGetValue(models.GUID, out mbase);
                    if (mbase is NodeModel)
                    {
                        annotationNodeModel.Add(mbase as NodeModel);
                    }
                    if (mbase is NoteModel)
                    {
                        annotationNoteModel.Add(mbase as NoteModel);
                    }
                }

                var annotationModel = new AnnotationModel(annotationNodeModel, annotationNoteModel)
                {
                    GUID = Guid.NewGuid(),
                    AnnotationText = annotation.AnnotationText,
                    Background = annotation.Background,
                    FontSize = annotation.FontSize
                };

                newAnnotations.Add(annotationModel);
            }

            // Add the new Annotation's to the Workspace
            foreach (var newAnnotation in newAnnotations)
            {
                CurrentWorkspace.AddAnnotation(newAnnotation);
                createdModels.Add(newAnnotation);
                AddToSelection(newAnnotation);
            }

            // adding an annotation overrides selection, so add nodes and notes after
            foreach (var item in newItems)
            {
                AddToSelection(item);
            }

            // Record models that are created as part of the command.
            CurrentWorkspace.RecordCreatedModels(createdModels);
        }
Esempio n. 31
0
        internal void BeginDragSelection(Point2D mouseCursor)
        {
            // This represents the first mouse-move event after the mouse-down
            // event. Note that a mouse-down event can either be followed by a
            // mouse-move event or simply a mouse-up event. That means having 
            // a click does not imply there will be a drag operation. That is 
            // the reason the first mouse-move event is used to signal the 
            // actual drag operation (as oppose to just click-and-release).
            // Here each node in the selection is being recorded for undo right
            // before they get updated by the drag operation.
            // 
            RecordSelectionForUndo();
            foreach (ISelectable selectable in DynamoSelection.Instance.Selection)
            {
                ILocatable locatable = selectable as ILocatable;
                if (null != locatable)
                    draggedNodes.Add(new DraggedNode(locatable, mouseCursor));
            }

            if (draggedNodes.Count <= 0) // There is nothing to drag.
            {
                string message = "Shouldn't get here if nothing is dragged";
                throw new InvalidOperationException(message);
            }
        }