예제 #1
0
        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);
        }
예제 #3
0
        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);
        }