예제 #1
0
        private Rect ResizeAndCentreExistingWindow(Size size)
        {
            // align window just like in macOS ...
            //
            // |10%|    80%    |10%|
            // |---|-----------|---|---
            // |TL |     T     |TR |10%
            // |---|-----------|---|---
            // |   |           |   |
            // |L  |     C     | R |80%
            // |   |           |   |
            // |---|-----------|---|---
            // |LB |     B     |RB |10%
            // |---|-----------|---|---

            var scale = DpiHelper.GetScaleFactorFromWindow(this);

            var limitPercentX = 0.1 * scale.Horizontal;
            var limitPercentY = 0.1 * scale.Vertical;

            // use absolute pixels for calculation
            var pxSize    = new Size(scale.Horizontal * size.Width, scale.Vertical * size.Height);
            var pxOldRect = this.GetWindowRectInPixel();

            // scale to new size, maintain centre
            var pxNewRect = Rect.Inflate(pxOldRect,
                                         (pxSize.Width - pxOldRect.Width) / 2,
                                         (pxSize.Height - pxOldRect.Height) / 2);

            var desktopRect = WindowHelper.GetDesktopRectFromWindowInPixel(this);

            var leftLimit   = desktopRect.Left + desktopRect.Width * limitPercentX;
            var rightLimit  = desktopRect.Right - desktopRect.Width * limitPercentX;
            var topLimit    = desktopRect.Top + desktopRect.Height * limitPercentY;
            var bottomLimit = desktopRect.Bottom - desktopRect.Height * limitPercentY;

            if (pxOldRect.Left < leftLimit && pxOldRect.Right < rightLimit) // L
            {
                pxNewRect.Location = new Point(Math.Max(pxOldRect.Left, desktopRect.Left), pxNewRect.Top);
            }
            else if (pxOldRect.Left > leftLimit && pxOldRect.Right > rightLimit) // R
            {
                pxNewRect.Location = new Point(Math.Min(pxOldRect.Right, desktopRect.Right) - pxNewRect.Width, pxNewRect.Top);
            }
            else // C, fix window boundary
            {
                pxNewRect.Offset(
                    Math.Max(0, desktopRect.Left - pxNewRect.Left) + Math.Min(0, desktopRect.Right - pxNewRect.Right), 0);
            }

            if (pxOldRect.Top < topLimit && pxOldRect.Bottom < bottomLimit) // T
            {
                pxNewRect.Location = new Point(pxNewRect.Left, Math.Max(pxOldRect.Top, desktopRect.Top));
            }
            else if (pxOldRect.Top > topLimit && pxOldRect.Bottom > bottomLimit) // B
            {
                pxNewRect.Location = new Point(pxNewRect.Left,
                                               Math.Min(pxOldRect.Bottom, desktopRect.Bottom) - pxNewRect.Height);
            }
            else // C, fix window boundary
            {
                pxNewRect.Offset(0,
                                 Math.Max(0, desktopRect.Top - pxNewRect.Top) + Math.Min(0, desktopRect.Bottom - pxNewRect.Bottom));
            }

            // return absolute location and relative size
            return(new Rect(pxNewRect.Location, size));
        }