Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WpfHelpers.ToEtoScreen/ToNativeScreen helper methods #2639

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Eto.Mac/SDConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ public static sd.PointF ToSD (this PointF point)
return new sd.PointF (point.X, point.Y);
}

public static sd.Point ToSDPoint (this PointF point)
{
return new sd.Point ((int)point.X, (int)point.Y);
}

internal static sd.PointF[] ToSD (this PointF[] points)
{
var result = new sd.PointF[points.Length];
Expand Down
18 changes: 9 additions & 9 deletions src/Eto.WinForms/Win32.dpi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ public static Eto.Drawing.Point LogicalToScreen(this Eto.Drawing.PointF point, E
{
screen = screen ?? Eto.Forms.Screen.FromPoint(point);
var sdscreen = ScreenHandler.GetControl(screen);
var location = sdscreen.GetLogicalLocation();
var pixelSize = sdscreen.GetLogicalPixelSize(usePerMonitor);
var location = sdscreen.GetBounds().Location;
var screenBounds = screen.Bounds;
var sdscreenBounds = usePerMonitor ? sdscreen.GetBounds() : sdscreen.Bounds.ToEto();

var x = location.X + (point.X - screenBounds.X) * pixelSize;
var y = location.Y + (point.Y - screenBounds.Y) * pixelSize;
var x = sdscreenBounds.X + (point.X - location.X) * pixelSize;
var y = sdscreenBounds.Y + (point.Y - location.Y) * pixelSize;

return Drawing.Point.Round(new Drawing.PointF(x, y));
}
Expand All @@ -76,10 +76,10 @@ public static Eto.Drawing.PointF ScreenToLogical(this Eto.Drawing.Point point, s

public static Eto.Drawing.PointF ScreenToLogical(this sd.Point point, swf.Screen sdscreen = null, bool usePerMonitor = true)
{
sdscreen = sdscreen ?? swf.Screen.FromPoint(point);
sdscreen ??= swf.Screen.FromPoint(point);
var location = sdscreen.GetLogicalLocation();
var pixelSize = sdscreen.GetLogicalPixelSize(usePerMonitor);
var sdscreenBounds = sdscreen.GetBounds();
var sdscreenBounds = usePerMonitor ? sdscreen.GetBounds() : sdscreen.Bounds.ToEto();

var x = location.X + (point.X - sdscreenBounds.X) / pixelSize;
var y = location.Y + (point.Y - sdscreenBounds.Y) / pixelSize;
Expand All @@ -93,10 +93,10 @@ public static Eto.Drawing.RectangleF ScreenToLogical(this Eto.Drawing.Rectangle
sdscreen = sdscreen ?? swf.Screen.FromPoint(rect.Location.ToSD());
var location = sdscreen.GetLogicalLocation();
var pixelSize = sdscreen.GetLogicalPixelSize(usePerMonitor);
var screenBounds = sdscreen.GetBounds();
var sdscreenBounds = usePerMonitor ? sdscreen.GetBounds() : sdscreen.Bounds.ToEto();
return new Eto.Drawing.RectangleF(
location.X + (rect.X - screenBounds.X) / pixelSize,
location.Y + (rect.Y - screenBounds.Y) / pixelSize,
location.X + (rect.X - sdscreenBounds.X) / pixelSize,
location.Y + (rect.Y - sdscreenBounds.Y) / pixelSize,
rect.Width / pixelSize,
rect.Height / pixelSize
);
Expand Down
70 changes: 0 additions & 70 deletions src/Eto.WinForms/WinConversions.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,76 +59,6 @@ public static sd.Color ToSD(this Color color)
return sd.Color.FromArgb((byte)(color.A * 255), (byte)(color.R * 255), (byte)(color.G * 255), (byte)(color.B * 255));
}

public static Point ToEto(this sd.Point point)
{
return new Point(point.X, point.Y);
}

public static PointF ToEto(this sd.PointF point)
{
return new PointF(point.X, point.Y);
}

public static sd.PointF ToSD(this PointF point)
{
return new sd.PointF(point.X, point.Y);
}

public static sd.Point ToSDPoint(this PointF point)
{
return new sd.Point((int)point.X, (int)point.Y);
}

public static Size ToEto(this sd.Size size)
{
return new Size(size.Width, size.Height);
}

public static sd.Size ToSD(this Size size)
{
return new sd.Size(size.Width, size.Height);
}

public static Size ToEtoF(this sd.SizeF size)
{
return new Size((int)size.Width, (int)size.Height);
}

public static SizeF ToEto(this sd.SizeF size)
{
return new SizeF(size.Width, size.Height);
}

public static sd.SizeF ToSD(this SizeF size)
{
return new sd.SizeF(size.Width, size.Height);
}

public static Rectangle ToEto(this sd.Rectangle rect)
{
return new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
}

public static RectangleF ToEto(this sd.RectangleF rect)
{
return new RectangleF(rect.X, rect.Y, rect.Width, rect.Height);
}

public static sd.Rectangle ToSD(this Rectangle rect)
{
return new sd.Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
}

public static sd.RectangleF ToSD(this RectangleF rect)
{
return new sd.RectangleF(rect.X, rect.Y, rect.Width, rect.Height);
}

public static sd.Rectangle ToSDRectangle(this RectangleF rect)
{
return new sd.Rectangle((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
}

internal static sd.Point[] ToSD(this Point[] points)
{
var result =
Expand Down
28 changes: 28 additions & 0 deletions src/Eto.Wpf/WpfHelpers.cs
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,33 @@ public static Window ToEtoWindow(IntPtr windowHandle)
return null;
return new Form(new HwndFormHandler(windowHandle));
}

/// <summary>
/// Converts a System.Drawing.Point in screen coordinates to an Eto point in screen coordinates.
/// </summary>
/// <param name="point">A point in Windows Forms/win32 screen coordinates.</param>
/// <returns>A point in Eto screen coordinates.</returns>
public static PointF ToEtoScreen(this sd.Point point, swf.Screen sdscreen = null, bool perMonitor = false) => Win32.ScreenToLogical(point, sdscreen, perMonitor);

public static RectangleF ToEtoScreen(this sd.Rectangle rect, swf.Screen sdscreen = null, bool perMonitor = false)
{
var topLeft = ToEtoScreen(rect.Location, sdscreen, perMonitor);
var bottomRight = ToEtoScreen(new sd.Point(rect.X + rect.Width, rect.Y + rect.Height), sdscreen, perMonitor);
return new RectangleF(topLeft, new SizeF(bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y));
}

/// <summary>
/// Converts a point in Eto screen coordinates to a point in Windows Forms/win32 screen coordinates.
/// </summary>
/// <param name="point">A point in Eto screen coordinates.</param>
/// <returns>A point in Windows Forms/win32 screen coordinates.</returns>
public static Point ToNativeScreen(this PointF point, Screen screen = null, bool perMonitor = false) => Win32.LogicalToScreen(point, screen, perMonitor);
public static Rectangle ToNativeScreen(this RectangleF rect, Screen screen = null, bool perMonitor = false)
{
var topLeft = rect.TopLeft.ToNativeScreen(screen, perMonitor);
var bottomRight = rect.BottomRight.ToNativeScreen(screen, perMonitor);
return new Rectangle(topLeft, new Size(bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y));
}

}
}
99 changes: 99 additions & 0 deletions test/Eto.Test.Wpf/UnitTests/ScreenToClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Eto.Test.UnitTests;
using NUnit.Framework;
using swf = System.Windows.Forms;
using sd = System.Drawing;

namespace Eto.Test.Wpf.UnitTests
{
[TestFixture]
public class ScreenToClientTests : TestBase
{

class NonActivatingForm : swf.Form
{
protected override bool ShowWithoutActivation => true;
}

[Test, ManualTest]
public void ScreenLocationsShouldBeCorrect()
{
var mre = new ManualResetEvent(false);
Invoke(() =>
{
var wfwindows = new List<swf.Form>();
var windows = new List<Window>();

void CreateWindow(Rectangle rect)
{
var window = new Form
{
ShowActivated = false,
ShowInTaskbar = false,
Minimizable = false,
Maximizable = false,
Bounds = rect,
Content = TableLayout.AutoSized("Click to dismiss", centered: true)
};
window.MouseDown += (sender, e) =>
{
foreach (var w in windows)
{
w.Close();
}
foreach (var w in wfwindows)
{
w.Close();
}
mre.Set();
};
window.Show();
windows.Add(window);

bool perMonitor = true;

var sdrect = WpfHelpers.ToNativeScreen(rect, window.Screen, perMonitor: perMonitor).ToSD();

var wfwindow = new NonActivatingForm
{
Bounds = sdrect,
ShowInTaskbar = false,
MinimizeBox = false,
MaximizeBox = false,
StartPosition = swf.FormStartPosition.Manual,
BackColor = sd.Color.Blue
};
wfwindow.Controls.Add(new swf.Label { Text = "Move me", Dock = swf.DockStyle.Fill, ForeColor = sd.Color.White });
wfwindow.LocationChanged += (sender, e) =>
{
var loc = wfwindow.RectangleToScreen(wfwindow.ClientRectangle);
window.Bounds = (Rectangle)WpfHelpers.ToEtoScreen(loc, swf.Screen.FromControl(wfwindow), perMonitor: perMonitor);
};
wfwindow.SizeChanged += (sender, e) =>
{
var loc = wfwindow.RectangleToScreen(wfwindow.ClientRectangle);
window.Bounds = (Rectangle)WpfHelpers.ToEtoScreen(loc, swf.Screen.FromControl(wfwindow), perMonitor: perMonitor);
};
wfwindow.Show();
wfwindows.Add(wfwindow);

}

foreach (var screen in Screen.Screens)
{
var bounds = (Rectangle)screen.WorkingArea;
var size = new Size(200, 200);
CreateWindow(new Rectangle(bounds.TopLeft, size));
CreateWindow(new Rectangle(bounds.TopRight - new Size(size.Width, 0), size));
CreateWindow(new Rectangle(bounds.BottomLeft - new Size(0, size.Height), size));
CreateWindow(new Rectangle(bounds.BottomRight - size, size));
}
});
mre.WaitOne();
}

}
}
Loading