|
18 | 18 | using System;
|
19 | 19 | using System.Diagnostics;
|
20 | 20 | using System.IO;
|
21 |
| -using System.Linq; |
22 | 21 | using System.Runtime.ExceptionServices;
|
23 | 22 | using System.Windows;
|
24 |
| -using System.Windows.Documents; |
25 | 23 | using System.Windows.Input;
|
26 | 24 | using System.Windows.Threading;
|
27 | 25 | using QuickLook.Common.Helpers;
|
@@ -62,49 +60,90 @@ internal void RunAndClose()
|
62 | 60 | BeginClose();
|
63 | 61 | }
|
64 | 62 |
|
65 |
| - private void ResizeAndCenter(Size size, bool canOldPluginResize, bool canNextPluginResize) |
| 63 | + private void ResizeAndCentre(Size size) |
66 | 64 | {
|
67 |
| - // resize to MinSize first |
68 |
| - size.Width = Math.Max(size.Width, MinWidth); |
69 |
| - size.Height = Math.Max(size.Height, MinHeight); |
70 |
| - |
71 | 65 | // if the window is now now maximized, do not move it
|
72 | 66 | if (WindowState == WindowState.Maximized)
|
73 | 67 | return;
|
74 | 68 |
|
75 |
| - var screen = WindowHelper.GetCurrentWindowRect(); |
76 |
| - |
77 |
| - // otherwise, resize it and place it to the old window center. |
78 |
| - var oldCenterX = Left + Width / 2; |
79 |
| - var oldCenterY = Top + Height / 2; |
80 |
| - |
81 |
| - var newLeft = oldCenterX - size.Width / 2; |
82 |
| - var newTop = oldCenterY - size.Height / 2; |
83 |
| - |
84 |
| - // ensure the new window is fully visible |
85 |
| - newLeft = Math.Max(newLeft, screen.Left); // left |
86 |
| - newTop = Math.Max(newTop, screen.Top); // top |
87 |
| - newLeft = newLeft + size.Width > screen.Right ? screen.Right - size.Width : newLeft; // right |
88 |
| - newTop = newTop + size.Height > screen.Bottom ? screen.Bottom - size.Height : newTop; // bottom |
| 69 | + var newRect = IsLoaded ? ResizeAndCentreExistingWindow(size) : ResizeAndCentreNewWindow(size); |
89 | 70 |
|
90 | 71 | if (IsLoaded)
|
91 | 72 | {
|
92 |
| - this.MoveWindow(newLeft, newTop, size.Width, size.Height); |
| 73 | + this.MoveWindow(newRect.Left, newRect.Top, newRect.Width, newRect.Height); |
93 | 74 | }
|
94 | 75 | else
|
95 | 76 | {
|
96 |
| - // MoveWindow does not work for new windows |
97 |
| - Width = size.Width; |
98 |
| - Height = size.Height; |
99 |
| - Left = newLeft; |
100 |
| - Top = newTop; |
101 |
| - if (double.IsNaN(Left) || double.IsNaN(Top)) // first time showing |
102 |
| - WindowStartupLocation = WindowStartupLocation.CenterScreen; |
103 |
| - |
104 |
| - Dispatcher.BeginInvoke(new Action(() => this.BringToFront(Topmost)), DispatcherPriority.Render); |
| 77 | + Top = newRect.Top; |
| 78 | + Left = newRect.Left; |
| 79 | + Width = newRect.Width; |
| 80 | + Height = newRect.Height; |
105 | 81 | }
|
106 | 82 | }
|
107 | 83 |
|
| 84 | + private Rect ResizeAndCentreExistingWindow(Size size) |
| 85 | + { |
| 86 | + // align window just like in macOS ... |
| 87 | + // |
| 88 | + // |10%| 80% |10%| |
| 89 | + // |---|-----------|---|--- |
| 90 | + // |TL | T |TR |10% |
| 91 | + // |---|-----------|---|--- |
| 92 | + // | | | | |
| 93 | + // |L | C | R |80% |
| 94 | + // | | | | |
| 95 | + // |---|-----------|---|--- |
| 96 | + // |LB | B |RB |10% |
| 97 | + // |---|-----------|---|--- |
| 98 | + |
| 99 | + const double limitPercentX = 0.1; |
| 100 | + const double limitPercentY = 0.1; |
| 101 | + |
| 102 | + var oldRect = new Rect(Left, Top, Width, Height); |
| 103 | + |
| 104 | + // scale to new size, maintain centre |
| 105 | + var newRect = Rect.Inflate(oldRect, |
| 106 | + (Math.Max(MinWidth, size.Width) - oldRect.Width) / 2, |
| 107 | + (Math.Max(MinHeight, size.Height) - oldRect.Height) / 2); |
| 108 | + |
| 109 | + var desktopRect = WindowHelper.GetDesktopRectFromWindow(this); |
| 110 | + |
| 111 | + var leftLimit = desktopRect.Left + desktopRect.Width * limitPercentX; |
| 112 | + var rightLimit = desktopRect.Right - desktopRect.Width * limitPercentX; |
| 113 | + var topLimit = desktopRect.Top + desktopRect.Height * limitPercentY; |
| 114 | + var bottomLimit = desktopRect.Bottom - desktopRect.Height * limitPercentY; |
| 115 | + |
| 116 | + if (oldRect.Left < leftLimit && oldRect.Right < rightLimit) // L |
| 117 | + newRect.Location = new Point(Math.Max(oldRect.Left, desktopRect.Left), newRect.Top); |
| 118 | + else if (oldRect.Left > leftLimit && oldRect.Right > rightLimit) // R |
| 119 | + newRect.Location = new Point(Math.Min(oldRect.Right, desktopRect.Right) - newRect.Width, newRect.Top); |
| 120 | + else // C, fix window boundary |
| 121 | + newRect.Offset( |
| 122 | + Math.Max(0, desktopRect.Left - newRect.Left) + Math.Min(0, desktopRect.Right - newRect.Right), 0); |
| 123 | + |
| 124 | + if (oldRect.Top < topLimit && oldRect.Bottom < bottomLimit) // T |
| 125 | + newRect.Location = new Point(newRect.Left, Math.Max(oldRect.Top, desktopRect.Top)); |
| 126 | + else if (oldRect.Top > topLimit && oldRect.Bottom > bottomLimit) // B |
| 127 | + newRect.Location = new Point(newRect.Left, |
| 128 | + Math.Min(oldRect.Bottom, desktopRect.Bottom) - newRect.Height); |
| 129 | + else // C, fix window boundary |
| 130 | + newRect.Offset(0, |
| 131 | + Math.Max(0, desktopRect.Top - newRect.Top) + Math.Min(0, desktopRect.Bottom - newRect.Bottom)); |
| 132 | + |
| 133 | + return newRect; |
| 134 | + } |
| 135 | + |
| 136 | + private Rect ResizeAndCentreNewWindow(Size size) |
| 137 | + { |
| 138 | + var desktopRect = WindowHelper.GetCurrentDesktopRect(); |
| 139 | + |
| 140 | + var newRect = Rect.Inflate(desktopRect, |
| 141 | + (Math.Max(MinWidth, size.Width) - desktopRect.Width) / 2, |
| 142 | + (Math.Max(MinHeight, size.Height) - desktopRect.Height) / 2); |
| 143 | + |
| 144 | + return newRect; |
| 145 | + } |
| 146 | + |
108 | 147 | internal void UnloadPlugin()
|
109 | 148 | {
|
110 | 149 | // the focused element will not processed by GC: https://stackoverflow.com/questions/30848939/memory-leak-due-to-window-efectivevalues-retention
|
@@ -164,7 +203,8 @@ internal void BeginShow(IViewer matchedPlugin, string path,
|
164 | 203 | else
|
165 | 204 | _ignoreNextWindowSizeChange = true;
|
166 | 205 |
|
167 |
| - ResizeAndCenter(newSize, _canOldPluginResize, ContextObject.CanResize); |
| 206 | + ResizeAndCentre(newSize); |
| 207 | + Dispatcher.BeginInvoke(new Action(() => this.BringToFront(Topmost)), DispatcherPriority.Render); |
168 | 208 |
|
169 | 209 | if (Visibility != Visibility.Visible)
|
170 | 210 | Show();
|
|
0 commit comments