internal ZoomEventArgs(Point2D offset, double focusWidth, double focusHeight) { this.Offset = offset; this.FocusWidth = focusWidth; this.FocusHeight = focusHeight; this.Modes = ZoomModes.ByFitView; }
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; }
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; } }
/// <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); }
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)); }
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)); }
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); }
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); }
/// <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); }
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); }
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); }
internal ZoomEventArgs(double zoom, Point2D point) { this.Point = point; this.Zoom = zoom; this.Modes = ZoomModes.ByPoint | ZoomModes.ByFactor; }
internal ZoomEventArgs(Point2D point) { this.Point = point; this.Modes = ZoomModes.ByPoint; }
public PointEventArgs(Point2D p) { Point = p; }
public bool Contains(Point2D point) { return(Contains(point.X, point.Y)); }
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); }
/// <summary> /// /// </summary> /// <param name="mouseCursor"></param> /// <param name="operation"></param> public DragSelectionCommand(Point2D mouseCursor, Operation operation) { MouseCursor = mouseCursor; DragOperation = operation; }
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); }
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); }
internal void EndDragSelection(Point2D mouseCursor) { UpdateDraggedSelection(mouseCursor); // Final position update. draggedNodes.Clear(); // We are no longer dragging anything. }
/// <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; } }
internal void PasteSelection(Point2D targetPoint) { stateMachine.PasteSelection(targetPoint); }
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)); }
/// <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; }
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; }
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(); }
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); }
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); }
/// <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); }
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); } }