public void Update(PopupPositionerParameters parameters) { // Simplify calculations var horizontalMargin = (parameters.AnchorRectangle.Width - parameters.Size.Width) / 2; var verticalMargin = (parameters.AnchorRectangle.Height - parameters.Size.Height) / 2; _popup.MoveAndResize(new Point(horizontalMargin, verticalMargin), parameters.Size / _popup.Scaling); }
public void Update(PopupPositionerParameters parameters) { var rect = Calculate( parameters.Size * _popup.Scaling, new Rect( parameters.AnchorRectangle.TopLeft * _popup.Scaling, parameters.AnchorRectangle.Size * _popup.Scaling), parameters.Anchor, parameters.Gravity, parameters.ConstraintAdjustment, parameters.Offset * _popup.Scaling); _popup.MoveAndResize( rect.Position, rect.Size / _popup.Scaling); }
private void Update(Size translatedSize, Size originalSize, Rect anchorRect, PopupPositioningEdge anchor, PopupPositioningEdge gravity, PopupPositionerConstraintAdjustment constraintAdjustment, Point offset) { var parentGeometry = _popup.ParentClientAreaScreenGeometry; anchorRect = anchorRect.Translate(parentGeometry.TopLeft); Rect GetBounds() { var screens = _popup.Screens; var targetScreen = screens.FirstOrDefault(s => s.Bounds.Contains(anchorRect.TopLeft)) ?? screens.FirstOrDefault(s => s.Bounds.Intersects(anchorRect)) ?? screens.FirstOrDefault(s => s.Bounds.Contains(parentGeometry.TopLeft)) ?? screens.FirstOrDefault(s => s.Bounds.Intersects(parentGeometry)) ?? screens.FirstOrDefault(); return(targetScreen?.WorkingArea ?? new Rect(0, 0, double.MaxValue, double.MaxValue)); } var bounds = GetBounds(); bool FitsInBounds(Rect rc, PopupPositioningEdge edge = PopupPositioningEdge.AllMask) { if ((edge & PopupPositioningEdge.Left) != 0 && rc.X < bounds.X) { return(false); } if ((edge & PopupPositioningEdge.Top) != 0 && rc.Y < bounds.Y) { return(false); } if ((edge & PopupPositioningEdge.Right) != 0 && rc.Right > bounds.Right) { return(false); } if ((edge & PopupPositioningEdge.Bottom) != 0 && rc.Bottom > bounds.Bottom) { return(false); } return(true); } Rect GetUnconstrained(PopupPositioningEdge a, PopupPositioningEdge g) => new Rect(Gravitate(GetAnchorPoint(anchorRect, a), translatedSize, g) + offset, translatedSize); var geo = GetUnconstrained(anchor, gravity); // If flipping geometry and anchor is allowed and helps, use the flipped one, // otherwise leave it as is if (!FitsInBounds(geo, PopupPositioningEdge.HorizontalMask) && (constraintAdjustment & PopupPositionerConstraintAdjustment.FlipX) != 0) { var flipped = GetUnconstrained(anchor.FlipX(), gravity.FlipX()); if (FitsInBounds(flipped, PopupPositioningEdge.HorizontalMask)) { geo = geo.WithX(flipped.X); } } // If sliding is allowed, try moving the rect into the bounds if ((constraintAdjustment & PopupPositionerConstraintAdjustment.SlideX) != 0) { geo = geo.WithX(Math.Max(geo.X, bounds.X)); if (geo.Right > bounds.Right) { geo = geo.WithX(bounds.Right - geo.Width); } } // If flipping geometry and anchor is allowed and helps, use the flipped one, // otherwise leave it as is if (!FitsInBounds(geo, PopupPositioningEdge.VerticalMask) && (constraintAdjustment & PopupPositionerConstraintAdjustment.FlipY) != 0) { var flipped = GetUnconstrained(anchor.FlipY(), gravity.FlipY()); if (FitsInBounds(flipped, PopupPositioningEdge.VerticalMask)) { geo = geo.WithY(flipped.Y); } } // If sliding is allowed, try moving the rect into the bounds if ((constraintAdjustment & PopupPositionerConstraintAdjustment.SlideY) != 0) { geo = geo.WithY(Math.Max(geo.Y, bounds.Y)); if (geo.Bottom > bounds.Bottom) { geo = geo.WithY(bounds.Bottom - geo.Height); } } _popup.MoveAndResize(geo.TopLeft, originalSize); }