protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (!e.Handled) { // Order of operations: // if marquee dragging // - apply delta to marquee // - test all components to see if they are within the marquee and set selection accordingly. // else if move dragging // - apply delta to all selected items // if we've started a drag if (m_dragStartPoint.HasValue) { e.Handled = true; Point currentPoint = e.GetPosition(GraphLayout); // if the marquee is visible, then we're doing a marquee selection. if (MarqueeAdorner.Visibility != System.Windows.Visibility.Collapsed) { var left = Math.Min(m_dragStartPoint.Value.X, currentPoint.X); var top = Math.Min(m_dragStartPoint.Value.Y, currentPoint.Y); var right = Math.Max(m_dragStartPoint.Value.X, currentPoint.X); var bottom = Math.Max(m_dragStartPoint.Value.Y, currentPoint.Y); // If the user has moved the mouse at all, then show the selection box. if (right != left || bottom != top) { MarqueeAdorner.Visibility = System.Windows.Visibility.Visible; } MarqueeAdorner.SetValue(Canvas.LeftProperty, left); MarqueeAdorner.SetValue(Canvas.TopProperty, top); MarqueeAdorner.Width = right - left; MarqueeAdorner.Height = bottom - top; Rect marqueeBounds = new Rect(new Point(left, top), new Point(right, bottom)); foreach (GraphSharp.Controls.VertexControl potentialSelectedVertex in GraphLayout.GetAllVertexControls()) { Rect vertexBounds = new Rect(new Point(potentialSelectedVertex.TopLeftX, potentialSelectedVertex.TopLeftY), new Size(potentialSelectedVertex.ActualWidth, potentialSelectedVertex.ActualHeight)); if (marqueeBounds.IntersectsWith(vertexBounds)) { SetIsSelected(potentialSelectedVertex, true); } else { SetIsSelected(potentialSelectedVertex, false); } } } else { Vector delta = currentPoint - m_lastDragPoint.Value; foreach (GraphSharp.Controls.VertexControl potentialSelectedVertex in s_selectedVertices) { potentialSelectedVertex.CenterX += delta.X; potentialSelectedVertex.CenterY += delta.Y; } } m_lastDragPoint = currentPoint; } } }
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); if (e.Handled != true) { // Hit-test order of operations // if hit: button // - this must happen first so that button presses do not start a drag-behaviour. // - do nothing // - return // if hit: vertex info // - do nothing // if hit: connection between vertexes // - do nothing // if hit: vertex // - select vertex (if not selected) // - prepare to start dragging // if hit: empty // - prepare marquee draw box // - prepare to start dragging bool shouldStartDragging = true; var hitElement = InputHitTest(e.GetPosition(this)) as DependencyObject; if (hitElement != null) { // If the user clicked on a button, then we don't want to do anything (let the button handle all the processing) if (hitElement.GetParent <Button>(this) != null) { shouldStartDragging = false; } // If the user clicked on an info panel, then we don't want to do anything (they exist "above" the graph and cannot be selected in the same way.) if (shouldStartDragging == true && hitElement.GetParent <TraceLab.UI.WPF.Views.Nodes.NodeInfoContainer>(this) != null) { shouldStartDragging = false; } // If the user clicked on an edge - do nothing, let the edge handle everything. if (shouldStartDragging == true && hitElement.GetParent <GraphSharp.Controls.EdgeControl>(this) != null) { shouldStartDragging = false; } // We're definitely going to start dragging _something_ - either the marquee or the current selection. if (shouldStartDragging == true) { e.Handled = true; m_dragStartPoint = e.GetPosition(GraphLayout); m_lastDragPoint = m_dragStartPoint.Value; var hitVertex = hitElement.GetParent <GraphSharp.Controls.VertexControl>(this); if (hitVertex != null) { // 1) if vertex is not already selected, then clear selection and select this vertex. if ((bool)hitVertex.GetValue(GraphView.IsSelectedProperty) == false) { UnselectAll(); SetIsSelected(hitVertex, true); } // 2) Begin dragging of entire selection // - nothing special needs to happen here, since we're prepared to start dragging // - and "marquee" dragging only happens if the marquee is NOT collapsed. } else { // Begin dragging marquee MarqueeAdorner.SetValue(Canvas.LeftProperty, m_dragStartPoint.Value.Y); MarqueeAdorner.SetValue(Canvas.TopProperty, m_dragStartPoint.Value.Y); MarqueeAdorner.Width = 1; MarqueeAdorner.Height = 1; MarqueeAdorner.Visibility = System.Windows.Visibility.Hidden; // Clear the selection in preparation. UnselectAll(); } } } // Take focus Focus(); } }