Browse Source

fix bugs in FormLocationHelper if working on high DPI displays

4.1
Siegfried Pammer 14 years ago
parent
commit
50a678c30c
  1. 36
      src/Main/Base/Project/Src/Gui/FormLocationHelper.cs
  2. 2
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs
  3. 9
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

36
src/Main/Base/Project/Src/Gui/FormLocationHelper.cs

@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -21,7 +21,7 @@ namespace ICSharpCode.SharpDevelop.Gui
if (isResizable) {
form.Bounds = Validate(PropertyService.Get(propertyName, GetDefaultBounds(form)));
} else {
form.Location = Validate(PropertyService.Get(propertyName, GetDefaultLocation(form)), form.Size);
form.Location = Validate(new System.Drawing.Rectangle(PropertyService.Get(propertyName, GetDefaultLocation(form)), form.Size)).Location;
}
form.Closing += delegate {
if (isResizable) {
@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.Gui
if (isResizable) {
Rect bounds = PropertyService.Get(propertyName, GetDefaultBounds(window));
bounds.Offset(ownerLocation.X, ownerLocation.Y);
bounds = Validate(bounds);
bounds = Validate(bounds.TransformToDevice(window).ToSystemDrawing()).ToWpf().TransformFromDevice(window);
window.Left = bounds.X;
window.Top = bounds.Y;
window.Width = bounds.Width;
@ -50,9 +50,9 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -50,9 +50,9 @@ namespace ICSharpCode.SharpDevelop.Gui
Size size = new Size(window.ActualWidth, window.ActualHeight);
Point location = PropertyService.Get(propertyName, GetDefaultLocation(window));
location.Offset(ownerLocation.X, ownerLocation.Y);
location = Validate(location, size);
window.Left = location.X;
window.Top = location.Y;
var bounds = Validate(new Rect(location, size).TransformToDevice(window).ToSystemDrawing()).ToWpf().TransformFromDevice(window);
window.Left = bounds.X;
window.Top = bounds.Y;
}
window.Closing += delegate {
var relativeToOwner = GetLocationRelativeToOwner(window);
@ -88,35 +88,25 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -88,35 +88,25 @@ namespace ICSharpCode.SharpDevelop.Gui
return new Point(owner.Left, owner.Top);
}
public static Rect Validate(Rect bounds)
/// <remarks>Requires Pixels!!!</remarks>
public static System.Drawing.Rectangle Validate(System.Drawing.Rectangle bounds)
{
// Check if form is outside the screen and get it back if necessary.
// This is important when the user uses multiple screens, a window stores its location
// on the secondary monitor and then the secondary monitor is removed.
LoggingService.InfoFormatted("Number of screens: {0}", Screen.AllScreens.Length);
foreach (var screen in Screen.AllScreens) {
var rect = System.Drawing.Rectangle.Intersect(bounds.ToSystemDrawing(), screen.WorkingArea);
var rect = System.Drawing.Rectangle.Intersect(bounds, screen.WorkingArea);
LoggingService.InfoFormatted("Screen {2}: Validating {0}; intersection {1}", bounds, rect, screen.Bounds);
if (rect.Width > 10 && rect.Height > 10)
return bounds;
}
// center on primary screen
LoggingService.InfoFormatted("Validating {0}; center on screen", bounds);
// TODO : maybe use screen where main window is most visible?
var targetScreen = Screen.PrimaryScreen;
return new Rect((targetScreen.WorkingArea.Width - bounds.Width) / 2, (targetScreen.WorkingArea.Height - bounds.Height) / 2, bounds.Width, bounds.Height);
}
static Point Validate(Point location, Size size)
{
return Validate(new Rect(location, size)).Location;
}
static System.Drawing.Rectangle Validate(System.Drawing.Rectangle bounds)
{
return Validate(bounds.ToWpf()).ToSystemDrawing();
}
static System.Drawing.Point Validate(System.Drawing.Point location, System.Drawing.Size size)
{
return Validate(location.ToWpf(), size.ToWpf()).ToSystemDrawing();
return new System.Drawing.Rectangle((targetScreen.WorkingArea.Width - bounds.Width) / 2, (targetScreen.WorkingArea.Height - bounds.Height) / 2, bounds.Width, bounds.Height);
}
static System.Drawing.Rectangle GetDefaultBounds(Form form)

2
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs

@ -59,7 +59,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -59,7 +59,7 @@ namespace ICSharpCode.SharpDevelop.Gui
void EnsureFloatingWindowsLocations()
{
foreach (var window in dockingManager.FloatingWindows) {
var newLocation = FormLocationHelper.Validate(new Rect(window.Left, window.Top, window.Width, window.Height));
var newLocation = FormLocationHelper.Validate(new Rect(window.Left, window.Top, window.Width, window.Height).TransformToDevice(window).ToSystemDrawing()).ToWpf().TransformFromDevice(window);
window.Left = newLocation.Left;
window.Top = newLocation.Top;
}

9
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -82,6 +82,13 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -82,6 +82,13 @@ namespace ICSharpCode.SharpDevelop.Gui
{
base.OnSourceInitialized(e);
HwndSource.FromHwnd(this.MainWin32Window.Handle).AddHook(SingleInstanceHelper.WndProc);
// validate after PresentationSource is initialized
Rect bounds = new Rect(Left, Top, Width, Height);
bounds = FormLocationHelper.Validate(bounds.TransformToDevice(this).ToSystemDrawing()).ToWpf().TransformFromDevice(this);
this.Left = bounds.Left;
this.Top = bounds.Top;
this.Width = bounds.Width;
this.Height = bounds.Height;
}
public void Initialize()
@ -554,7 +561,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -554,7 +561,7 @@ namespace ICSharpCode.SharpDevelop.Gui
public void SetMemento(Properties memento)
{
Rect bounds = memento.Get("Bounds", new Rect(10, 10, 750, 550));
bounds = FormLocationHelper.Validate(bounds);
// bounds are validated after PresentationSource is initialized (see OnSourceInitialized)
this.Left = bounds.Left;
this.Top = bounds.Top;
this.Width = bounds.Width;

Loading…
Cancel
Save