private ElementPosition AdjustFitWithinBounds(Rectangle element, Rectangle target, Rectangle bounding, PositionDirectionalHintData positionData, double gap = 0) { var alignmentEdge = positionData.AlignmentEdge; var alignTargetEdge = positionData.AlignTargetEdge; ElementPosition elementEstimate = new ElementPosition(element, positionData.TargetEdge, alignmentEdge); if (!DirectionalHintFixed && !CoverTarget) { elementEstimate = FlipToFit(element, target, bounding, positionData, gap); } var outOfBounds = GetOutOfBoundsEdges(element, bounding); if (alignTargetEdge) { // The edge opposite to the alignment edge might be out of bounds. Flip alignment to see if we can get it within bounds. if (elementEstimate.AlignmentEdge != RectangleEdge.None && outOfBounds.IndexOf((RectangleEdge)((int)elementEstimate.AlignmentEdge * -1)) > -1) { var flippedElementEstimate = FlipAlignmentEdge(elementEstimate, target, gap); if (IsRectangleWithinBounds(flippedElementEstimate.ElementRectangle, bounding)) { return(flippedElementEstimate); } } } else { foreach (var direction in outOfBounds) { elementEstimate.ElementRectangle = AlignEdges(elementEstimate.ElementRectangle, bounding, direction); } } return(elementEstimate); }
private ElementPosition FlipAlignmentEdge(ElementPosition elementEstimate, Rectangle target, double gap) { var alignmentEdge = elementEstimate.AlignmentEdge; var targetEdge = elementEstimate.TargetEdge; var elementRectangle = elementEstimate.ElementRectangle; var oppositeEdge = (RectangleEdge)((int)alignmentEdge * -1); var newEstimate = EstimatePosition(elementRectangle, target, new PositionDirectionalHintData(targetEdge, oppositeEdge), gap); return(new ElementPosition(newEstimate, targetEdge, oppositeEdge)); }
private CalloutBeakPositionedInfo FinalizeBeakPosition(ElementPosition elementPosition, Rectangle positionedBeak, Rectangle bounds) { var targetEdge = (RectangleEdge)((int)elementPosition.TargetEdge * -1); var actualElement = new Rectangle(0, elementPosition.ElementRectangle.width, 0, elementPosition.ElementRectangle.height); PartialRectangle returnValue = new PartialRectangle(); var returnEdge = FinalizeReturnEdge( elementPosition.ElementRectangle, elementPosition.AlignmentEdge != RectangleEdge.None ? elementPosition.AlignmentEdge : GetFlankingEdges(targetEdge).positiveEdge, bounds); switch (targetEdge) { case RectangleEdge.Bottom: returnValue.bottom = GetEdgeValue(positionedBeak, targetEdge); break; case RectangleEdge.Left: returnValue.left = GetEdgeValue(positionedBeak, targetEdge); break; case RectangleEdge.Right: returnValue.right = GetEdgeValue(positionedBeak, targetEdge); break; case RectangleEdge.Top: returnValue.top = GetEdgeValue(positionedBeak, targetEdge); break; } switch (returnEdge) { case RectangleEdge.Bottom: returnValue.bottom = GetRelativeEdgeDifference(positionedBeak, actualElement, returnEdge); break; case RectangleEdge.Left: returnValue.left = GetRelativeEdgeDifference(positionedBeak, actualElement, returnEdge); break; case RectangleEdge.Right: returnValue.right = GetRelativeEdgeDifference(positionedBeak, actualElement, returnEdge); break; case RectangleEdge.Top: returnValue.top = GetRelativeEdgeDifference(positionedBeak, actualElement, returnEdge); break; } return(new CalloutBeakPositionedInfo( returnValue, GetClosestEdge(elementPosition.TargetEdge, positionedBeak, actualElement), targetEdge)); }