private async Task <ElementPositionInfo> PositionElementRelativeAsync(double gap, Rectangle targetRect, Rectangle boundingRect) { //previous data... not implemented //RTL ... not implemented //GetPositionData() PositionDirectionalHintData positionData = DirectionalDictionary[DirectionalHint]; //PositionDirectionalHintData alignmentData = null; //GetAlignmentData() if (positionData.IsAuto) { positionData.AlignmentEdge = GetClosestEdge(positionData.TargetEdge, targetRect, boundingRect); } positionData.AlignTargetEdge = AlignTargetEdge; //Now calculate positionedElement //GetRectangleFromElement() var calloutRectangle = await JSRuntime.InvokeAsync <Rectangle>("BlazorFabricBaseComponent.measureElementRect", calloutReference); //Debug.WriteLine($"Callout: {calloutRectangle.left}, {calloutRectangle.top}, {calloutRectangle.right}, {calloutRectangle.bottom}"); var positionedElement = PositionElementWithinBounds(calloutRectangle, targetRect, boundingRect, positionData, gap); var elementPositionInfo = positionedElement.ToElementPositionInfo(targetRect); return(elementPositionInfo); }
private ElementPosition FlipToFit(Rectangle rect, Rectangle target, Rectangle bounding, PositionDirectionalHintData positionData, double gap = 0) { var currentEstimate = rect; var currentEdge = positionData.TargetEdge; var currentAlignment = positionData.AlignmentEdge; List <RectangleEdge> directions = new List <RectangleEdge> { RectangleEdge.Left, RectangleEdge.Right, RectangleEdge.Bottom, RectangleEdge.Top }; for (var i = 0; i < 4; i++) { if (IsEdgeInBounds(currentEstimate, bounding, currentEdge)) { directions.RemoveAt(directions.IndexOf(currentEdge)); if ((int)directions.IndexOf((RectangleEdge)((int)currentEdge * -1)) > -1) { currentEdge = (RectangleEdge)((int)currentEdge * -1); } else { currentAlignment = currentEdge; currentEdge = directions[0]; } currentEstimate = EstimatePosition(rect, target, new PositionDirectionalHintData(currentEdge, currentAlignment), gap); } else { return(new ElementPosition(currentEstimate, currentEdge, currentAlignment)); } } return(new ElementPosition(rect, positionData.TargetEdge, currentAlignment)); }
private Rectangle EstimatePosition(Rectangle elementToPosition, Rectangle target, PositionDirectionalHintData positionData, double gap = 0) { var elementEdge = this.CoverTarget ? positionData.TargetEdge : (RectangleEdge)((int)positionData.TargetEdge * -1); Rectangle estimatedElementPosition = null; estimatedElementPosition = this.CoverTarget ? AlignEdges(elementToPosition, target, positionData.TargetEdge, gap) : AlignOppositeEdges(elementToPosition, target, positionData.TargetEdge, gap); if (positionData.AlignmentEdge == RectangleEdge.None) { var targetMiddlePoint = GetCenterValue(target, positionData.TargetEdge); estimatedElementPosition = CenterEdgeToPoint(estimatedElementPosition, elementEdge, targetMiddlePoint); } else { estimatedElementPosition = AlignEdges(estimatedElementPosition, target, positionData.AlignmentEdge); } return(estimatedElementPosition); }
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 PositionElementWithinBounds(Rectangle elementToPosition, Rectangle target, Rectangle bounding, PositionDirectionalHintData positionData, double gap) { var estimatedElementPosition = EstimatePosition(elementToPosition, target, positionData, gap); if (IsRectangleWithinBounds(estimatedElementPosition, bounding)) { return(new ElementPosition(estimatedElementPosition, positionData.TargetEdge, positionData.AlignmentEdge)); } else { return(AdjustFitWithinBounds(elementToPosition, target, bounding, positionData, gap)); } }