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; }
protected override void OnDragOver(DragEventArgs e) { var currentPosition = e.GetPosition(WorkspaceElements); // create adorner if it is necessary if (draggedAdorner == null) { var adornerLayer = AdornerLayer.GetAdornerLayer(WorkspaceElements); draggedAdorner = new DraggedAdorner(draggedData, draggedSelectionTemplate, WorkspaceElements, adornerLayer); } var zoom = ViewModel.Zoom; var xOffset = currentPosition.X - initialMousePosition.X; var yOffset = currentPosition.Y - initialMousePosition.Y; // compute (x; y) so that dragged selection has mouse cursor // in the same place as origin selection does var x = xOffset * zoom; var y = yOffset * zoom; // compute bounds of dragged content so that it does not go outside dragged canvas var x1 = -ViewModel.Model.X/zoom - xOffset; var y1 = -ViewModel.Model.Y/zoom - yOffset; var x2 = WorkspaceElements.RenderSize.Width / zoom; var y2 = WorkspaceElements.RenderSize.Height / zoom; var bounds = new Rect(x1, y1, x2, y2); draggedAdorner.SetPosition(x, y, bounds); }
/// <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; } }