/// <summary> /// Pulled directly from Reflector disassembly /// </summary> private LineSegment[] CalculateSegments(IGeometryHost geometryHost, DiagramHitTestInfo hitTestInfo) { IBinaryLinkGeometryData data1 = geometryHost as IBinaryLinkGeometryData; EdgePointCollection collection1 = data1.GeometryEdgePointsNoJumps; LineSegment[] segmentArray1 = new LineSegment[collection1.Count - 1]; Pen pen1 = geometryHost.GeometryStyleSet.GetPen(this.GetOutlinePenId(geometryHost)); if (pen1 != null) { for (int num1 = 0; num1 < (collection1.Count - 1); num1++) { RectangleD ed1 = GeometryHelpers.RectangleDFrom2Pts(collection1[num1].Point, collection1[num1 + 1].Point); // In DSL Tools v8.2, GetHitTestTolerance is an instance method, but in DSL Tools v9.0, it is a static method. // We call it without a qualifier here so that it will compile against both versions. SizeD ed2 = GetHitTestTolerance(hitTestInfo); if (ed1.Height < ed2.Height) { ed1.Inflate(0, (pen1.Width / 2f) + ed2.Height); } else if (ed1.Width < ed2.Width) { ed1.Inflate((pen1.Width / 2f) + ed2.Width, 0); } segmentArray1[num1] = new LineSegment(collection1[num1].Point, collection1[num1 + 1].Point, num1, num1 + 1, num1 == 0, (num1 + 1) == (collection1.Count - 1), ed1); } } return(segmentArray1); }
/// <summary> /// Override of BinaryLinkShape.ExcludeFromClipRegion to support moving the link /// decorator and properly rotating it. /// </summary> public override void ExcludeFromClipRegion(Graphics g, Matrix matrix, GraphicsPath perimeter) { ObliqueBinaryLinkShapeGeometry geometry = this.ShapeGeometry as ObliqueBinaryLinkShapeGeometry; Pen linePen = this.StyleSet.GetPen(DiagramPens.ConnectionLine); EdgePointCollection edgePoints = this.EdgePoints; int edgePointCount = edgePoints.Count; if ((geometry != null) && (linePen != null)) { for (int i = 1; i < edgePointCount; ++i) { if (edgePoints[i].Flag == VGPointType.JumpEnd) { GraphicsPath excludePath = this.ExcludePath; geometry.AddLineArcPath(excludePath, edgePoints[i - 1].Point, edgePoints[i].Point); g.SetClip(excludePath, CombineMode.Exclude); } else { RectangleD excludeRect = GeometryHelpers.RectangleDFrom2Pts(edgePoints[i - 1].Point, edgePoints[i].Point); double inflateBy = linePen.Width / 2f; excludeRect.Inflate(inflateBy, inflateBy); g.SetClip(RectangleD.ToRectangleF(excludeRect), CombineMode.Exclude); } } if (edgePointCount > 1) { LinkDecorator decorator; #if VISUALSTUDIO_10_0 IBinaryLinkGeometryData geometryData = (IBinaryLinkGeometryData)this; #endif if (null != (decorator = DecoratorFrom)) { ExcludeDecorator(g, geometry, decorator, edgePoints[0].Point, edgePoints[1].Point #if VISUALSTUDIO_10_0 , geometryData.GeometryDecoratorFromSize #endif ); } if (null != (decorator = DecoratorTo)) { ExcludeDecorator(g, geometry, decorator, edgePoints[edgePointCount - 1].Point, edgePoints[edgePointCount - 2].Point #if VISUALSTUDIO_10_0 , geometryData.GeometryDecoratorToSize #endif ); } } } }
/// <summary> /// Override of DoHitTest so it works with non-rectilinear line segments /// </summary> public override bool DoHitTest(IGeometryHost geometryHost, PointD hitPoint, DiagramHitTestInfo hitTestInfo, bool includeTolerance) { bool retVal = false; LineSegment hitSegment = null; AnchorPoint anchorPoint = null; // In DSL Tools v8.2, GetHitTestTolerance is an instance method, but in DSL Tools v9.0, it is a static method. // We call it without a qualifier here so that it will compile against both versions. SizeD tolerance = GetHitTestTolerance(hitTestInfo); RectangleD perimeter = this.GetPerimeterBoundingBox(geometryHost); perimeter.Inflate(tolerance); if (perimeter.Contains(hitPoint)) { LineSegment[] segments = this.CalculateSegments(geometryHost, hitTestInfo); int segmentCount = segments.Length; for (int i = 0; i < segmentCount; ++i) { LineSegment testSegment = segments[i]; RectangleD testBounds = GeometryHelpers.RectangleDFrom2Pts(testSegment.StartPoint, testSegment.EndPoint); testBounds.Inflate(tolerance); if (testBounds.Contains(hitPoint)) { anchorPoint = TestHitAnchor(geometryHost as BinaryLinkShape, testSegment, tolerance, hitPoint); if (anchorPoint != null) { retVal = true; hitSegment = testSegment; break; } double distance = DistanceFromPointToLine(hitPoint, testSegment.StartPoint, testSegment.EndPoint, true); if (!double.IsNaN(distance) && distance < (tolerance.Width + geometryHost.GeometryStyleSet.GetPen(geometryHost.GeometryOutlinePenId).Width / 2f)) { retVal = true; hitSegment = testSegment; break; } } } } if (hitTestInfo != null) { DiagramItem diagramItem; if (retVal) { if (anchorPoint == null) { // In DSL Tools v8.2, CreateDiagramItem is an instance method, but in DSL Tools v9.0, it is a static method. // We call it without a qualifier here so that it will compile against both versions. diagramItem = CreateDiagramItem(geometryHost, hitSegment); } else { diagramItem = new DiagramItem(geometryHost as LinkShape, hitSegment, anchorPoint); } } else { diagramItem = null; } hitTestInfo.HitDiagramItem = diagramItem; hitTestInfo.HitGrabHandle = null; } return(retVal); }