protected override void OnRender(DrawingContext drawingContext) { var parentPanel = VisualTreeUtils.GetParent <ConnectionsPanel>(this); if (parentPanel == null) { return; } var connection = DataContext as Connection; var layoutInfo = parentPanel.GetLayoutInfo(connection); var dx = (layoutInfo.toPoint.X - layoutInfo.fromPoint.X) / parentPanel.Zoom; var dy = (layoutInfo.toPoint.Y - layoutInfo.fromPoint.Y) / parentPanel.Zoom; const float margin = 10; Point[] points; if (dx < 0) { double marginY = 80; if (dy > 40 && dy < 140) { marginY = dy + 30; } var s = -Math.Sign(dy - marginY); // This is a connection from right to left points = new Point[] { new Point(margin, 0), new Point(margin + margin / 2, margin / 2), new Point(margin + margin / 2, marginY - margin / 2), new Point(margin, marginY), new Point(dx - margin, marginY), new Point(dx - margin - margin / 2, marginY - margin / 2 * s), new Point(dx - margin - margin / 2, dy + margin / 2 * s), new Point(dx - margin, dy), new Point(dx, dy) }; } else { var height = Math.Abs(dy); var s = Math.Sign(dy); var width = dx - 2 * margin; if (height > width) { var displacement = height - width; points = new Point[] { new Point(margin, 0), new Point(margin + width / 2, width / 2 * s), new Point(margin + width / 2, width / 2 * s + displacement * s), new Point(dx - margin, height * s), new Point(dx, height * s) }; } else { var displacement = width - height; points = new Point[] { new Point(margin, 0), new Point(margin + height / 2, height / 2 * s), new Point(margin + height / 2 + displacement, height / 2 * s), new Point(dx - margin, height * s), new Point(dx, height * s) }; } } var figure = new PathFigure(); figure.IsClosed = false; figure.IsFilled = false; figure.StartPoint = new Point(0, 0); figure.Segments.Add(new PolyLineSegment(points, true)); var geo = new PathGeometry(); geo.Figures.Add(figure); const float outlineSize = 10; Pen shapeOutlinePen; if (IsShadow) { shapeOutlinePen = new Pen(Brush, outlineSize); } else { shapeOutlinePen = new Pen(getMultipliedAlpha255(Brush, 0.4f), outlineSize); } Pen shapeOutlinePen2 = new Pen(getMultipliedAlpha255(Brush, 1.5f), outlineSize); drawingContext.DrawGeometry(null, shapeOutlinePen, geo); if (!IsShadow) { Pen shapeInlinePen = new Pen(Brush, outlineSize - 2); drawingContext.DrawGeometry(null, shapeInlinePen, geo); } if (connection.FromNode != null) { drawingContext.DrawLine(shapeOutlinePen2, new Point(-margin, -2), new Point(0, -2)); } if (connection.ToNode != null) { drawingContext.DrawLine(shapeOutlinePen2, new Point(dx + margin, dy - 2), new Point(dx, dy - 2)); } }
private void InvalidateNodesAndConnectionsPanels() { VisualTreeUtils.GetItemsHost(NodesItemsControl).InvalidateMeasure(); VisualTreeUtils.GetItemsHost(ConnectionsItemsControl).InvalidateMeasure(); }
protected override Size ArrangeOverride(Size finalSize) { var NodeEditorControl = VisualTreeUtils.GetVisualParent <NodeEditorControl>(this); ItemsControl nodesItemsControl = null; CartesianPanel nodesCartesianPanel = null; if (NodeEditorControl != null) { nodesItemsControl = NodeEditorControl.GetNodesItemsControl(); nodesCartesianPanel = VisualTreeUtils.GetItemsHost(nodesItemsControl) as CartesianPanel; } if (nodesItemsControl == null) { foreach (UIElement child in InternalChildren) { if (child == null) { continue; } child.Arrange(new Rect(new Point(0, 0), new Size(0, 0))); } } else { var zoom = this.Zoom; var connectionsItemsControl = ItemsControl.GetItemsOwner(this) as ItemsControl; var connectionsGenerator = connectionsItemsControl == null ? null : connectionsItemsControl.ItemContainerGenerator; var nodesGenerator = nodesItemsControl.ItemContainerGenerator; foreach (UIElement child in InternalChildren) { if (child == null) { continue; } Connection connection; if (connectionsGenerator != null) { connection = connectionsGenerator.ItemFromContainer(child) as Connection; } else if (child as ContentControl != null) { connection = (child as ContentControl).Content as Connection; } else if ((child as FrameworkElement).DataContext as Connection != null) { connection = (child as FrameworkElement).DataContext as Connection; } else { // ??? connection = null; } var verticalOutputOffset = 47.0 + 20.0 * connection.FromNode.GetOutputIndex(connection.FromNodeOutput); var fromNodeContainer = nodesGenerator.ContainerFromItem(connection.FromNode) as FrameworkElement; if (!fromNodeContainer.IsArrangeValid) { this.InvalidateArrange(); return(finalSize); } var fromNodeOrigin = fromNodeContainer.TranslatePoint(new Point(0, 0), nodesItemsControl); var fromNodeSize = nodesCartesianPanel.GetNodeSizeInfo(connection.FromNode).Size; fromNodeSize = new Size(fromNodeSize.Width * zoom, fromNodeSize.Height * zoom); Point fromPoint = new Point(fromNodeOrigin.X + fromNodeSize.Width, fromNodeOrigin.Y + verticalOutputOffset * zoom); Point toNodeOrigin; double verticalInputOffset; if (connection.ToNode != null) { var toNodeContainer = nodesGenerator.ContainerFromItem(connection.ToNode) as FrameworkElement; if (!toNodeContainer.IsArrangeValid) { this.InvalidateArrange(); return(finalSize); } toNodeOrigin = toNodeContainer.TranslatePoint(new Point(0, 0), nodesItemsControl); //var toNodeSize = nodesCartesianPanel.GetNodeSizeInfo(connection.ToNode).Size; //toNodeSize = new Size(toNodeSize.Width * zoom, // toNodeSize.Height * zoom); verticalInputOffset = 47.0 + 20.0 * connection.ToNode.GetInputIndex(connection.ToNodeInput); } else { //toNodeOrigin = NodeEditorControl.previewMousePosition; toNodeOrigin = Mouse.GetPosition(this); verticalInputOffset = 0; //child.RenderTransform = new ScaleTransform(zoom, zoom); //child.Arrange(new Rect(childOrigin, new Size(100, 50))); //continue; } var toPoint = new Point(toNodeOrigin.X, toNodeOrigin.Y + verticalInputOffset * zoom); mLayoutInfo[connection] = new ConnectionPathLayoutInfo() { fromPoint = fromPoint, toPoint = toPoint }; // We're making an assumption on the visual tree here. // Invalidate the visual of the descendant, assuming it's a ConnectionPath which needs to do so var cp = child as ContentPresenter; if (cp != null) { (VisualTreeHelper.GetChild(cp, 0) as UIElement).InvalidateVisual(); } child.RenderTransform = new ScaleTransform(zoom, zoom); //child.Arrange(new Rect(fromPoint, childSize)); child.Arrange(new Rect(fromPoint, new Size(1, 1))); } } return(finalSize); }