/// <summary> /// Detect and show path when dragging /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void OnDragDelta_DetectPath(object sender, DragDeltaEventArgs e) { AdornerDataThumb <ModelItem, Connector> thumb = sender as AdornerDataThumb <ModelItem, Connector>; Point currentPoint = thumb.Data.Position + new Vector(e.HorizontalChange, e.VerticalChange); Connector target = HitTest(thumb, currentPoint); ModelItem item = thumb.AdornedParent; Canvas canvas = item.ContainerCanvas; #if DEBUG_ON // test value System.Console.WriteLine("{0} Dragging - connItem {1} ", System.DateTime.Now.Millisecond, drawingConn); #endif if (drawingConn == null) { // create new connection drawingConn = new ConnectionItem(); // get current connection type Window w = Window.GetWindow(canvas); ConnectionType connType = (ConnectionType)(w.FindName("CurrentConnectionType") as ComboBox).SelectedIndex; drawingConn.ContentObject.Type = connType.ToString(); drawingConn.ContentObject.Source = thumb.Data; // bind source here Diagram diagram = Project.Current.Children.FindByCanvas(canvas); diagram.Children.Add(drawingConn.ContentObject); } if ((drawingConn.ContentObject.Sink = target) != null) { drawingConn.UpdatePath(); } else { drawingConn.UpdatePath(drawingConn.ContentObject.SinkPosition = currentPoint); } drawingConn.Draw(); e.Handled = true; }
private AdornerDataThumb <ModelItem, Connector> GetConnectorThumb(Connector conn) { AdornerDataThumb <ModelItem, Connector> thumb = new AdornerDataThumb <ModelItem, Connector>(AdornedElement as ModelItem, conn); thumb.Style = FindResource("ConnectorStyle_" + conn.Type.ToString()) as Style; thumb.DragDelta += OnDragDelta_DetectPath; thumb.DragCompleted += OnDragCompleted_Connect; return(thumb); }
/// <summary> /// Do hit test, if the target is a thumb (another connector), then return it /// </summary> /// <param name="hitPoint"></param> /// <returns></returns> private static Connector HitTest(AdornerDataThumb <ModelItem, Connector> thumb, Point hitPoint) { ModelItem elem = thumb.AdornedParent; Canvas canvas = elem.ContainerCanvas; HitTestResult hitRes = VisualTreeHelper.HitTest(canvas, hitPoint); DependencyObject hitObj = null; Model model = elem.ContentObject; ModelItem res = null; if (hitRes != null) { hitObj = hitRes.VisualHit; } while (hitObj != null && hitObj != canvas && (res = hitObj as ModelItem) == null) { hitObj = VisualTreeHelper.GetParent(hitObj); } #if DEBUG_ON // test value System.Console.WriteLine("{0} hitObj {1} ", System.DateTime.Now.Millisecond, hitObj.GetType()); #endif // test fails if (res == null || res == elem) { return(null); } // spilit the rectangle into four areas with two line: y=-h/w*x+h, y=h/w*x double width = res.Size.Width, height = res.Size.Height; Vector relativeVector = hitPoint - res.Position; double y1 = relativeVector.X * height / width, y2 = -y1 + height; ConnectorType type = ConnectorType.Center; // now calculate which connector is that if (relativeVector.Y < y1 && relativeVector.Y < y2) { type = ConnectorType.Top; } else if (relativeVector.Y > y1 && relativeVector.Y < y2) { type = ConnectorType.Left; } else if (relativeVector.Y > y1 && relativeVector.Y > y2) { type = ConnectorType.Bottom; } else if (relativeVector.Y < y1 && relativeVector.Y > y2) { type = ConnectorType.Right; } #if DEBUG_ON // test value System.Console.WriteLine("{0} Connector.Type {1} width {2} height {3}", System.DateTime.Now.Millisecond, type.ToString(), width, height); #endif return(res.ContentObject.GetConnector(type)); }
/// <summary> /// When drag is completed, i.e. mouse up /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private static void OnDragCompleted_Connect(object sender, DragCompletedEventArgs e) { AdornerDataThumb <ModelItem, Connector> thumb = sender as AdornerDataThumb <ModelItem, Connector>; Point currentPoint = thumb.Data.Position + new Vector(e.HorizontalChange, e.VerticalChange); Connector target = HitTest(thumb, currentPoint); ModelItem item = thumb.AdornedParent; Canvas canvas = item.ContainerCanvas; #if DEBUG_ON // test value System.Console.WriteLine("{0} DragCompleted - connItem {1} ", System.DateTime.Now.Millisecond, drawingConn); #endif if (drawingConn != null) { // if target is empty, cancel the connection if (drawingConn.ContentObject.Sink == null) { Diagram diagram = Project.Current.Children.FindByCanvas(canvas); diagram.Children.Remove(drawingConn.ContentObject); } drawingConn = null; } e.Handled = true; }