/** * This is called from OperatorWidget while dragging from OperatorWidget during onDragConnectionDelta */ public void UpdateDuringConstruction(Point endPoint) { if (Source.Outputs.Count <= 0) { return; } var sourceUI = Source as UIElement; if (UIHelper.FindParent <CompositionGraphView>(sourceUI) == null) { Logger.Warn("Tried to connect to source that is not in current view (" + Output.Parent.Name + ")."); return; } Point sourcePointInMainPanel = Source.PositionOnCanvas; double targetY = endPoint.Y; double sourceY = sourcePointInMainPanel.Y; double targetXmin, targetXmax; targetXmin = endPoint.X; targetXmax = endPoint.X; IsSelected = false; int outputCount = Source.Outputs.Count; int outputIndex = Output.Func.EvaluationIndex; double outputWidth = Source.Width / outputCount; double sourceXmin = sourcePointInMainPanel.X + (double)outputIndex * outputWidth; double sourceXmax = sourceXmin + outputWidth; // Calculate straight factor from overlap double BLEND_RANGE = 40; double BLEND_BORDER = 10; double overlapp = Math.Min(sourceXmax, targetXmax) - Math.Max(sourceXmin, targetXmin); double straightFactor = Math.Min(BLEND_RANGE, Math.Max(0, overlapp - BLEND_BORDER)) / BLEND_RANGE; // limit straight connection to a certain y range... double STRAIGHT_MIN_DISTANCE = 50; double STRAIGHT_DISTANCE_BLEND = 50; double dy = sourceY - targetY; if (dy < -2) { straightFactor = 0.0; } else { straightFactor *= 1 - (Utilities.Clamp(dy, STRAIGHT_MIN_DISTANCE, STRAIGHT_MIN_DISTANCE + STRAIGHT_DISTANCE_BLEND) - STRAIGHT_MIN_DISTANCE) / STRAIGHT_DISTANCE_BLEND; } // Calculate curviness const double MIN_TANGENT_LENGTH = 80.0; const double MAX_TANGENT_LENGTH = 200.0; double tangent = Utilities.Clamp(((sourceY - targetY) * 0.4), MIN_TANGENT_LENGTH, MAX_TANGENT_LENGTH) * (1 - straightFactor); // Blend X depending on straightfactor double sourceXcenter = sourceXmin + 0.5 * (sourceXmax - sourceXmin); double targetXcenter = targetXmin + 0.5 * (targetXmax - targetXmin); double averageX = Math.Max(sourceXmin, targetXmin) + 0.5 * overlapp; double sourceX = sourceXcenter * (1 - straightFactor) + straightFactor * averageX; double targetX = targetXcenter * (1 - straightFactor) + straightFactor * averageX; m_TargetPoint = new Point(targetX, targetY); m_SourcePoint = new Point(sourceX, sourceY); m_PathFigure.StartPoint = new Point(sourceX, sourceY); m_CurveSegment.Point1 = new Point(sourceX, sourceY - tangent); m_CurveSegment.Point2 = new Point(targetX, targetY + tangent); m_CurveSegment.Point3 = new Point(targetX, targetY); m_ArrowHeadPathFigure.StartPoint = new Point(targetX, targetY + 2.02); m_ArrowHeadLineSegment.Point = new Point(targetX, targetY + 2); }
private void CreateLineGeometry() { //GradientPath = new GradientPath(); //GradientStop s2= new GradientStop(Colors.BrightColorFromType(Source.Type), offset:0.95); //GradientStop s1= new GradientStop(Colors.ColorFromType(Source.Type), offset: 0.8); //GradientPath.GradientStops.Add(s1); //GradientPath.GradientStops.Add(s2); //GradientPath.GradientMode = GradientMode.Parallel; //GradientPath.StrokeThickness = 0.5; //GradientPath.Tolerance= 0.2; //GradientPath.IsHitTestVisible= false; ConnectionPath = new Path(); //ConnectionPath.IsHitTestVisible = false; ConnectionPath.Stroke = new SolidColorBrush(UIHelper.BrightColorFromType(Output.Type)); ConnectionPath.Stroke.Freeze(); ConnectionPath.StrokeThickness = 3; ConnectionPath.StrokeEndLineCap = PenLineCap.Triangle; this.Children.Add(ConnectionPath); ConnectionPath2 = new Path(); //ConnectionPath2.IsHitTestVisible = false; ConnectionPath2.Stroke = new SolidColorBrush(UIHelper.ColorFromType(Output.Type)); ConnectionPath2.Stroke.Freeze(); ConnectionPath2.StrokeThickness = 2.0; ConnectionPath2.StrokeEndLineCap = PenLineCap.Triangle; this.Children.Add(ConnectionPath2); //this.Children.Add(GradientPath); PathGeometry pathGeometry = new PathGeometry(); pathGeometry.FillRule = FillRule.Nonzero; // Spline curve m_PathFigure = new PathFigure(); m_PathFigure.StartPoint = new Point(10, 10); pathGeometry.Figures.Add(m_PathFigure); m_CurveSegment = new BezierSegment(); m_CurveSegment.Point1 = new Point(10, 10); m_CurveSegment.Point2 = new Point(10, 10); m_CurveSegment.Point3 = new Point(10, 10); m_PathFigure.Segments.Add(m_CurveSegment); ConnectionPath.Data = pathGeometry; ConnectionPath2.Data = pathGeometry; //GradientPath.Data = pathGeometry; // ArrowHead m_ArrowHeadPath = new Path(); m_ArrowHeadPath.IsHitTestVisible = false; m_ArrowHeadPath.Stroke = new SolidColorBrush(UIHelper.BrightColorFromType(Output.Type)); m_ArrowHeadPath.Stroke.Freeze(); m_ArrowHeadPath.StrokeThickness = 14; m_ArrowHeadPath.StrokeEndLineCap = PenLineCap.Triangle; this.Children.Add(m_ArrowHeadPath); PathGeometry ArrowHeadPathGeometry = new PathGeometry(); ArrowHeadPathGeometry.FillRule = FillRule.Nonzero; m_ArrowHeadPathFigure = new PathFigure(); m_ArrowHeadPathFigure.StartPoint = new Point(10, 10); ArrowHeadPathGeometry.Figures.Add(m_ArrowHeadPathFigure); m_ArrowHeadLineSegment = new LineSegment(); m_ArrowHeadLineSegment.Point = new Point(10, -10); m_ArrowHeadPathFigure.Segments.Add(m_ArrowHeadLineSegment); m_ArrowHeadPath.Data = ArrowHeadPathGeometry; // Head thumb _thumb = new Thumb(); _thumb.Opacity = 0; this.Children.Add(_thumb); Canvas.SetTop(_thumb, -0.5 * CONNECTION_ARROW_THUMB_SIZE); _thumb.Width = CONNECTION_ARROW_THUMB_SIZE; Canvas.SetLeft(_thumb, -0.5 * CONNECTION_ARROW_THUMB_SIZE); _thumb.Height = CONNECTION_ARROW_THUMB_SIZE; _thumb.Loaded += Thumb_LoadedHandler; this.Unloaded += Thumb_UnloadEventHandler; }
/* * Calculates connection curve as described in http://streber.pixtur.de/index.php?go=fileDownloadAsImage&file=4964 */ public void Update() { if (Target == null) { return; } if (Source.Outputs.Count <= 0) { return; } if (Target.Inputs.Count <= 0) { return; } var targetUI = Target as UIElement; if (UIHelper.FindParent <CompositionGraphView>(targetUI) == null) { Logger.Warn("Tried to connect to TargetWidget that is not in current view (" + Input.Parent.Name + "). Please report this bug."); return; } var sourceUI = Source as UIElement; if (UIHelper.FindParent <CompositionGraphView>(sourceUI) == null) { Logger.Warn("Tried to connect to source that is not in current view (" + Output.Parent.Name + "). Please report this bug."); return; } Point targetPositionOnCanvas = Target.PositionOnCanvas; Point sourcePointInMainPanel = Source.PositionOnCanvas; double targetY = targetPositionOnCanvas.Y + Target.Height + 1.0; double sourceY = sourcePointInMainPanel.Y + 1.0; int index = this.GetMultiInputIndex(); Rect range = Target.GetRangeForInputConnectionLine(Input, index, false); double targetXmin = targetPositionOnCanvas.X + range.Left; double targetXmax = targetPositionOnCanvas.X + range.Right; double targetXcenter = targetXmin + 0.5 * (targetXmax - targetXmin); int outputCount = Source.Outputs.Count; int outputIndex = Output.Func.EvaluationIndex; double outputWidth = Source.Width / outputCount; double sourceXmin = sourcePointInMainPanel.X + (double)outputIndex * outputWidth; double sourceXmax = sourceXmin + outputWidth; double sourceXcenter = sourceXmin + 0.5 * (sourceXmax - sourceXmin); // Calculate straight factor from overlap const double BLEND_RANGE = 20; const double BLEND_BORDER = 10; double overlapp = Math.Min(sourceXmax, targetXmax) - Math.Max(sourceXmin, targetXmin); double straightFactor = Math.Min(BLEND_RANGE, Math.Max(0, overlapp - BLEND_BORDER)) / BLEND_RANGE; // limit straight connection to a certain y range... const double STRAIGHT_MIN_DISTANCE = 80; const double STRAIGHT_DISTANCE_BLEND = 50; double dy = sourceY - targetY; if (dy < -2) { straightFactor = 0.0; } else { straightFactor *= 1 - (Utilities.Clamp(dy, STRAIGHT_MIN_DISTANCE, STRAIGHT_MIN_DISTANCE + STRAIGHT_DISTANCE_BLEND) - STRAIGHT_MIN_DISTANCE) / STRAIGHT_DISTANCE_BLEND; } // Calculate curviness double MIN_TANGENT_LENGTH = 80.0; double MAX_TANGENT_LENGTH = 200.0; double tangent = Utilities.Clamp((sourceY - targetY) * 0.4, MIN_TANGENT_LENGTH, MAX_TANGENT_LENGTH) * (1 - straightFactor); // Blend X depending on straight factor double averageX = Math.Max(sourceXmin, targetXmin) + 0.5 * overlapp; double sourceX = sourceXcenter * (1 - straightFactor) + straightFactor * averageX; double targetX = targetXcenter * (1 - straightFactor) + straightFactor * averageX; m_PathFigure.StartPoint = new Point(sourceX, sourceY); m_CurveSegment.Point1 = new Point(sourceX, sourceY - tangent); m_CurveSegment.Point2 = new Point(targetX, targetY + tangent); m_CurveSegment.Point3 = new Point(targetX, targetY); m_ArrowHeadPathFigure.StartPoint = new Point(targetX, targetY + 2.02); m_ArrowHeadLineSegment.Point = new Point(targetX, targetY + 2); m_TargetPoint = new Point(targetX, targetY); m_SourcePoint = new Point(sourceX, sourceY); Canvas.SetLeft(_thumb, targetX - 0.5 * CONNECTION_ARROW_THUMB_SIZE); Canvas.SetTop(_thumb, targetY - 0.5 * CONNECTION_ARROW_THUMB_SIZE); }