From 4ec2b1c554d729fac656a1622be305ca390c291a Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 18 Jan 2019 11:06:16 +0100 Subject: [PATCH] Use PixelPoint and PixelRect for device points/rects. The affected members are: - `IWindowBaseImpl.Position` - `IWindowBaseImpl.PositionChanged` - `ITopLevelImpl.PointToClient` - `ITopLevelImpl.PointToScreen` - `IMouseDevice.Position` - `Screen.Bounds` - `Screen.WorkingArea` --- samples/ControlCatalog/Pages/ScreenPage.cs | 4 ++- .../Platform/SkiaPlatform/PopupImpl.cs | 6 ++-- .../Platform/SkiaPlatform/TopLevelImpl.cs | 8 ++--- .../Offscreen/OffscreenTopLevelImpl.cs | 4 +-- src/Avalonia.Controls/PixelPointEventArgs.cs | 27 +++++++++++++++++ .../Platform/ITopLevelImpl.cs | 4 +-- .../Platform/IWindowBaseImpl.cs | 6 ++-- src/Avalonia.Controls/Platform/Screen.cs | 8 ++--- src/Avalonia.Controls/PointEventArgs.cs | 27 ----------------- src/Avalonia.Controls/Primitives/Popup.cs | 30 ++++++++----------- src/Avalonia.Controls/Primitives/PopupRoot.cs | 10 +++---- src/Avalonia.Controls/Screens.cs | 14 ++++----- src/Avalonia.Controls/ToolTip.cs | 1 + src/Avalonia.Controls/TopLevel.cs | 8 ++--- src/Avalonia.Controls/Window.cs | 20 ++++++++++--- src/Avalonia.Controls/WindowBase.cs | 10 +++---- .../Remote/PreviewerWindowImpl.cs | 4 +-- src/Avalonia.DesignerSupport/Remote/Stubs.cs | 10 +++---- src/Avalonia.Input/IMouseDevice.cs | 2 +- src/Avalonia.Input/MouseDevice.cs | 2 +- src/Avalonia.Native/Helpers.cs | 15 ++++++++++ src/Avalonia.Native/ScreenImpl.cs | 5 +++- src/Avalonia.Native/WindowImplBase.cs | 14 ++++----- src/Avalonia.Visuals/Rendering/IRenderRoot.cs | 8 ++--- src/Avalonia.Visuals/VisualExtensions.cs | 12 +++++--- src/Avalonia.X11/X11Screens.cs | 16 +++++----- src/Avalonia.X11/X11Window.cs | 20 +++++++------ src/Gtk/Avalonia.Gtk3/GtkScreen.cs | 4 +-- src/Gtk/Avalonia.Gtk3/ScreenImpl.cs | 4 +-- src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs | 14 ++++----- .../FramebufferToplevelImpl.cs | 4 +-- .../Wpf/WpfInteropExtensions.cs | 2 ++ .../Wpf/WpfTopLevelImpl.cs | 4 +-- src/Windows/Avalonia.Win32/OleDropTarget.cs | 2 +- src/Windows/Avalonia.Win32/ScreenImpl.cs | 6 ++-- src/Windows/Avalonia.Win32/WinScreen.cs | 4 +-- src/Windows/Avalonia.Win32/WindowImpl.cs | 22 +++++++------- src/iOS/Avalonia.iOS/TopLevelImpl.cs | 4 +-- .../ButtonTests.cs | 4 +-- .../ContextMenuTests.cs | 2 +- .../ItemsPresenterTests_Virtualization.cs | 22 +++----------- ...emsPresenterTests_Virtualization_Simple.cs | 28 +++-------------- .../WindowTests.cs | 22 +++++++------- tests/Avalonia.UnitTests/TestRoot.cs | 4 +-- tests/Avalonia.UnitTests/TestTemplatedRoot.cs | 4 +-- 45 files changed, 227 insertions(+), 224 deletions(-) create mode 100644 src/Avalonia.Controls/PixelPointEventArgs.cs delete mode 100644 src/Avalonia.Controls/PointEventArgs.cs diff --git a/samples/ControlCatalog/Pages/ScreenPage.cs b/samples/ControlCatalog/Pages/ScreenPage.cs index fd66185832..b5c6892885 100644 --- a/samples/ControlCatalog/Pages/ScreenPage.cs +++ b/samples/ControlCatalog/Pages/ScreenPage.cs @@ -4,6 +4,7 @@ using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.Media; using Avalonia.Platform; +using Avalonia.Rendering; namespace ControlCatalog.Pages { @@ -23,6 +24,7 @@ namespace ControlCatalog.Pages base.Render(context); Window w = (Window)VisualRoot; Screen[] screens = w.Screens.All; + var scaling = ((IRenderRoot)w).RenderScaling; Pen p = new Pen(Brushes.Black); if (screens != null) @@ -56,7 +58,7 @@ namespace ControlCatalog.Pages text.Text = $"Primary: {screen.Primary}"; context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 40), text); - text.Text = $"Current: {screen.Equals(w.Screens.ScreenFromBounds(new Rect(w.Position, w.Bounds.Size)))}"; + text.Text = $"Current: {screen.Equals(w.Screens.ScreenFromBounds(new PixelRect(w.Position, PixelSize.FromSize(w.Bounds.Size, scaling))))}"; context.DrawText(Brushes.Black, boundsRect.Position.WithY(boundsRect.Size.Height + 60), text); } diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs index d55755d6e3..e89414d1f8 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs @@ -10,10 +10,10 @@ namespace Avalonia.Android.Platform.SkiaPlatform { class PopupImpl : TopLevelImpl, IPopupImpl { - private Point _position; + private PixelPoint _position; private bool _isAdded; Action IWindowBaseImpl.Activated { get; set; } - public Action PositionChanged { get; set; } + public Action PositionChanged { get; set; } public Action Deactivated { get; set; } public PopupImpl() : base(ActivityTracker.Current, true) @@ -36,7 +36,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform public IScreenImpl Screen { get; } - public Point Position + public PixelPoint Position { get { return _position; } set diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs index 8e8886269c..f42faeaa63 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs @@ -99,14 +99,14 @@ namespace Avalonia.Android.Platform.SkiaPlatform if (_view.Holder?.Surface?.IsValid == true) _view.Invalidate(); } - public Point PointToClient(Point point) + public Point PointToClient(PixelPoint point) { - return point; + return point.ToPoint(1); } - public Point PointToScreen(Point point) + public PixelPoint PointToScreen(Point point) { - return point; + return PixelPoint.FromPoint(point, 1); } public void SetCursor(IPlatformHandle cursor) diff --git a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs index 37bb72e75a..d328e1ee88 100644 --- a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs +++ b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs @@ -49,9 +49,9 @@ namespace Avalonia.Controls.Embedding.Offscreen public Action ScalingChanged { get; set; } public void SetInputRoot(IInputRoot inputRoot) => InputRoot = inputRoot; - public virtual Point PointToClient(Point point) => point; + public virtual Point PointToClient(PixelPoint point) => point.ToPoint(1); - public virtual Point PointToScreen(Point point) => point; + public virtual PixelPoint PointToScreen(Point point) => PixelPoint.FromPoint(point, 1); public virtual void SetCursor(IPlatformHandle cursor) { diff --git a/src/Avalonia.Controls/PixelPointEventArgs.cs b/src/Avalonia.Controls/PixelPointEventArgs.cs new file mode 100644 index 0000000000..55a3d5601f --- /dev/null +++ b/src/Avalonia.Controls/PixelPointEventArgs.cs @@ -0,0 +1,27 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; + +namespace Avalonia.Controls +{ + /// + /// Provides data for events. + /// + public class PixelPointEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// The data. + public PixelPointEventArgs(PixelPoint point) + { + Point = point; + } + + /// + /// Gets the data. + /// + public PixelPoint Point { get; } + } +} diff --git a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs index 60e25d2be6..8d8ce35c38 100644 --- a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs +++ b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs @@ -82,14 +82,14 @@ namespace Avalonia.Platform /// /// The point in screen coordinates. /// The point in client coordinates. - Point PointToClient(Point point); + Point PointToClient(PixelPoint point); /// /// Converts a point from client to screen coordinates. /// /// The point in client coordinates. /// The point in screen coordinates. - Point PointToScreen(Point point); + PixelPoint PointToScreen(Point point); /// /// Sets the cursor associated with the toplevel. diff --git a/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs b/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs index e788b3c73e..817eb3a25b 100644 --- a/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs +++ b/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs @@ -27,14 +27,14 @@ namespace Avalonia.Platform void BeginResizeDrag(WindowEdge edge); /// - /// Gets position of the window relatively to the screen + /// Gets the position of the window relative in device pixels. /// - Point Position { get; set; } + PixelPoint Position { get; set; } /// /// Gets or sets a method called when the window's position changes. /// - Action PositionChanged { get; set; } + Action PositionChanged { get; set; } /// /// Activates the window. diff --git a/src/Avalonia.Controls/Platform/Screen.cs b/src/Avalonia.Controls/Platform/Screen.cs index 5aa8c2c392..e7c811235c 100644 --- a/src/Avalonia.Controls/Platform/Screen.cs +++ b/src/Avalonia.Controls/Platform/Screen.cs @@ -2,17 +2,17 @@ { public class Screen { - public Rect Bounds { get; } + public PixelRect Bounds { get; } - public Rect WorkingArea { get; } + public PixelRect WorkingArea { get; } public bool Primary { get; } - public Screen(Rect bounds, Rect workingArea, bool primary) + public Screen(PixelRect bounds, PixelRect workingArea, bool primary) { this.Bounds = bounds; this.WorkingArea = workingArea; this.Primary = primary; } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Controls/PointEventArgs.cs b/src/Avalonia.Controls/PointEventArgs.cs deleted file mode 100644 index 4173d367d0..0000000000 --- a/src/Avalonia.Controls/PointEventArgs.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) The Avalonia Project. All rights reserved. -// Licensed under the MIT license. See licence.md file in the project root for full license information. - -using System; - -namespace Avalonia.Controls -{ - /// - /// Provides data for events. - /// - public class PointEventArgs : EventArgs - { - /// - /// Initializes a new instance of the class. - /// - /// The data. - public PointEventArgs(Point point) - { - Point = point; - } - - /// - /// Gets the data. - /// - public Point Point { get; } - } -} diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs index 5e79711f5a..d9070197b6 100644 --- a/src/Avalonia.Controls/Primitives/Popup.cs +++ b/src/Avalonia.Controls/Primitives/Popup.cs @@ -380,7 +380,7 @@ namespace Avalonia.Controls.Primitives /// Gets the position for the popup based on the placement properties. /// /// The popup's position in screen coordinates. - protected virtual Point GetPosition() + protected virtual PixelPoint GetPosition() { var result = GetPosition(PlacementTarget ?? this.GetVisualParent(), PlacementMode, PopupRoot, HorizontalOffset, VerticalOffset); @@ -388,35 +388,31 @@ namespace Avalonia.Controls.Primitives return result; } - internal static Point GetPosition(Control target, PlacementMode placement, PopupRoot popupRoot, double horizontalOffset, double verticalOffset) + internal static PixelPoint GetPosition(Control target, PlacementMode placement, PopupRoot popupRoot, double horizontalOffset, double verticalOffset) { - var zero = default(Point); - var mode = placement; - - if (target?.GetVisualRoot() == null) - { - mode = PlacementMode.Pointer; - } + var root = target?.GetVisualRoot(); + var mode = root != null ? placement : PlacementMode.Pointer; + var scaling = root?.RenderScaling ?? 1; switch (mode) { case PlacementMode.Pointer: if (popupRoot != null) { - // Scales the Horizontal and Vertical offset to screen co-ordinates. - var screenOffset = new Point(horizontalOffset * (popupRoot as ILayoutRoot).LayoutScaling, - verticalOffset * (popupRoot as ILayoutRoot).LayoutScaling); - return (((IInputRoot)popupRoot)?.MouseDevice?.Position ?? default(Point)) + screenOffset; + var screenOffset = PixelPoint.FromPoint(new Point(horizontalOffset, verticalOffset), scaling); + var mouseOffset = ((IInputRoot)popupRoot)?.MouseDevice?.Position ?? default; + return new PixelPoint( + screenOffset.X + mouseOffset.X, + screenOffset.Y + mouseOffset.Y); } - return default(Point); + return default; case PlacementMode.Bottom: - return target?.PointToScreen(new Point(0 + horizontalOffset, target.Bounds.Height + verticalOffset)) ?? - zero; + return target?.PointToScreen(new Point(0 + horizontalOffset, target.Bounds.Height + verticalOffset)) ?? default; case PlacementMode.Right: - return target?.PointToScreen(new Point(target.Bounds.Width + horizontalOffset, 0 + verticalOffset)) ?? zero; + return target?.PointToScreen(new Point(target.Bounds.Width + horizontalOffset, 0 + verticalOffset)) ?? default; default: throw new InvalidOperationException("Invalid value for Popup.PlacementMode"); diff --git a/src/Avalonia.Controls/Primitives/PopupRoot.cs b/src/Avalonia.Controls/Primitives/PopupRoot.cs index 286f7df3b9..59a8933b4b 100644 --- a/src/Avalonia.Controls/Primitives/PopupRoot.cs +++ b/src/Avalonia.Controls/Primitives/PopupRoot.cs @@ -85,18 +85,18 @@ namespace Avalonia.Controls.Primitives if (screen != null) { var scaling = VisualRoot.RenderScaling; - - var screenX = Position.X + (Bounds.Width * scaling) - screen.Bounds.X; - var screenY = Position.Y + (Bounds.Height * scaling) - screen.Bounds.Y; + var bounds = PixelRect.FromRect(Bounds, scaling); + var screenX = Position.X + bounds.Width - screen.Bounds.X; + var screenY = Position.Y + bounds.Height - screen.Bounds.Y; if (screenX > screen.Bounds.Width) { - Position = Position.WithX(Position.X - (screenX - screen.Bounds.Width)); + Position = Position.WithX(Position.X - screenX - bounds.Width); } if (screenY > screen.Bounds.Height) { - Position = Position.WithY(Position.Y - (screenY - screen.Bounds.Height)); + Position = Position.WithY(Position.Y - screenY - bounds.Height); } } } diff --git a/src/Avalonia.Controls/Screens.cs b/src/Avalonia.Controls/Screens.cs index 2bfddc048b..5a90adadbd 100644 --- a/src/Avalonia.Controls/Screens.cs +++ b/src/Avalonia.Controls/Screens.cs @@ -18,7 +18,7 @@ namespace Avalonia.Controls _iScreenImpl = iScreenImpl; } - public Screen ScreenFromBounds(Rect bounds){ + public Screen ScreenFromBounds(PixelRect bounds){ Screen currMaxScreen = null; double maxAreaSize = 0; @@ -39,16 +39,16 @@ namespace Avalonia.Controls return currMaxScreen; } - public Screen ScreenFromPoint(Point point) + public Screen ScreenFromPoint(PixelPoint point) { - return All.FirstOrDefault(x=>x.Bounds.Contains(point)); + return All.FirstOrDefault(x => x.Bounds.Contains(point)); } public Screen ScreenFromVisual(IVisual visual) { - Point tl = visual.PointToScreen(visual.Bounds.TopLeft); - Point br = visual.PointToScreen(visual.Bounds.BottomRight); - return ScreenFromBounds(new Rect(tl,br)); + var tl = visual.PointToScreen(visual.Bounds.TopLeft); + var br = visual.PointToScreen(visual.Bounds.BottomRight); + return ScreenFromBounds(new PixelRect(tl, br)); } } -} \ No newline at end of file +} diff --git a/src/Avalonia.Controls/ToolTip.cs b/src/Avalonia.Controls/ToolTip.cs index 28d1ba5e0f..018779c994 100644 --- a/src/Avalonia.Controls/ToolTip.cs +++ b/src/Avalonia.Controls/ToolTip.cs @@ -236,6 +236,7 @@ namespace Avalonia.Controls _popup = new PopupRoot { Content = this, }; ((ISetLogicalParent)_popup).SetParent(control); + _popup.Position = Popup.GetPosition(control, GetPlacement(control), _popup, GetHorizontalOffset(control), GetVerticalOffset(control)); _popup.Show(); diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs index 5443baf225..9be6d2004a 100644 --- a/src/Avalonia.Controls/TopLevel.cs +++ b/src/Avalonia.Controls/TopLevel.cs @@ -233,15 +233,15 @@ namespace Avalonia.Controls } /// - Point IRenderRoot.PointToClient(Point p) + Point IRenderRoot.PointToClient(PixelPoint p) { - return PlatformImpl?.PointToClient(p) ?? default(Point); + return PlatformImpl?.PointToClient(p) ?? default; } /// - Point IRenderRoot.PointToScreen(Point p) + PixelPoint IRenderRoot.PointToScreen(Point p) { - return PlatformImpl?.PointToScreen(p) ?? default(Point); + return PlatformImpl?.PointToScreen(p) ?? default; } /// diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs index 46916efc1d..4306ecf338 100644 --- a/src/Avalonia.Controls/Window.cs +++ b/src/Avalonia.Controls/Window.cs @@ -462,19 +462,31 @@ namespace Avalonia.Controls void SetWindowStartupLocation() { + var scaling = PlatformImpl?.Scaling ?? 1; + + // TODO: We really need non-client size here. + var rect = new PixelRect( + PixelPoint.Origin, + PixelSize.FromSize(ClientSize, scaling)); + if (WindowStartupLocation == WindowStartupLocation.CenterScreen) { - var screen = Screens.ScreenFromPoint(Bounds.Position); + var screen = Screens.ScreenFromPoint(Position); if (screen != null) - Position = screen.WorkingArea.CenterRect(new Rect(ClientSize)).Position; + { + Position = screen.WorkingArea.CenterRect(rect).Position; + } } else if (WindowStartupLocation == WindowStartupLocation.CenterOwner) { if (Owner != null) { - var positionAsSize = Owner.ClientSize / 2 - ClientSize / 2; - Position = Owner.Position + new Point(positionAsSize.Width, positionAsSize.Height); + // TODO: We really need non-client size here. + var ownerRect = new PixelRect( + Owner.Position, + PixelSize.FromSize(Owner.ClientSize, scaling)); + Position = ownerRect.CenterRect(rect).Position; } } } diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs index f609432545..2fba8619c6 100644 --- a/src/Avalonia.Controls/WindowBase.cs +++ b/src/Avalonia.Controls/WindowBase.cs @@ -81,7 +81,7 @@ namespace Avalonia.Controls /// /// Fired when the window position is changed. /// - public event EventHandler PositionChanged; + public event EventHandler PositionChanged; [CanBeNull] public new IWindowBaseImpl PlatformImpl => (IWindowBaseImpl) base.PlatformImpl; @@ -98,9 +98,9 @@ namespace Avalonia.Controls /// /// Gets or sets the window position in screen coordinates. /// - public Point Position + public PixelPoint Position { - get { return PlatformImpl?.Position ?? default(Point); } + get { return PlatformImpl?.Position ?? PixelPoint.Origin; } set { if (PlatformImpl is IWindowBaseImpl impl) @@ -267,9 +267,9 @@ namespace Avalonia.Controls /// . /// /// The window position. - private void HandlePositionChanged(Point pos) + private void HandlePositionChanged(PixelPoint pos) { - PositionChanged?.Invoke(this, new PointEventArgs(pos)); + PositionChanged?.Invoke(this, new PixelPointEventArgs(pos)); } /// diff --git a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs index cff59f2f8b..dc01bcb07e 100644 --- a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs +++ b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs @@ -35,8 +35,8 @@ namespace Avalonia.DesignerSupport.Remote { } - public Point Position { get; set; } - public Action PositionChanged { get; set; } + public PixelPoint Position { get; set; } + public Action PositionChanged { get; set; } public Action Deactivated { get; set; } public Action Activated { get; set; } public Func Closing { get; set; } diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs index 8f5b97af41..d849bfc021 100644 --- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs +++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs @@ -29,8 +29,8 @@ namespace Avalonia.DesignerSupport.Remote public Func Closing { get; set; } public Action Closed { get; set; } public IMouseDevice MouseDevice { get; } = new MouseDevice(); - public Point Position { get; set; } - public Action PositionChanged { get; set; } + public PixelPoint Position { get; set; } + public Action PositionChanged { get; set; } public WindowState WindowState { get; set; } public Action WindowStateChanged { get; set; } public IRenderer CreateRenderer(IRenderRoot root) => new ImmediateRenderer(root); @@ -45,9 +45,9 @@ namespace Avalonia.DesignerSupport.Remote { } - public Point PointToClient(Point point) => point; + public Point PointToClient(PixelPoint p) => p.ToPoint(1); - public Point PointToScreen(Point point) => point; + public PixelPoint PointToScreen(Point p) => PixelPoint.FromPoint(p, 1); public void SetCursor(IPlatformHandle cursor) { @@ -157,6 +157,6 @@ namespace Avalonia.DesignerSupport.Remote public int ScreenCount => 1; public Screen[] AllScreens { get; } = - {new Screen(new Rect(0, 0, 4000, 4000), new Rect(0, 0, 4000, 4000), true)}; + {new Screen(new PixelRect(0, 0, 4000, 4000), new PixelRect(0, 0, 4000, 4000), true)}; } } diff --git a/src/Avalonia.Input/IMouseDevice.cs b/src/Avalonia.Input/IMouseDevice.cs index 58e2222295..a1d1bb3eb8 100644 --- a/src/Avalonia.Input/IMouseDevice.cs +++ b/src/Avalonia.Input/IMouseDevice.cs @@ -11,6 +11,6 @@ namespace Avalonia.Input /// /// Gets the mouse position, in screen coordinates. /// - Point Position { get; } + PixelPoint Position { get; } } } diff --git a/src/Avalonia.Input/MouseDevice.cs b/src/Avalonia.Input/MouseDevice.cs index e01dedeede..4855dd0c56 100644 --- a/src/Avalonia.Input/MouseDevice.cs +++ b/src/Avalonia.Input/MouseDevice.cs @@ -54,7 +54,7 @@ namespace Avalonia.Input /// /// Gets the mouse position, in screen coordinates. /// - public Point Position + public PixelPoint Position { get; protected set; diff --git a/src/Avalonia.Native/Helpers.cs b/src/Avalonia.Native/Helpers.cs index c9d1256e91..a77e7d4ff8 100644 --- a/src/Avalonia.Native/Helpers.cs +++ b/src/Avalonia.Native/Helpers.cs @@ -12,11 +12,21 @@ namespace Avalonia.Native return new Point(pt.X, pt.Y); } + public static PixelPoint ToAvaloniaPixelPoint(this AvnPoint pt) + { + return new PixelPoint((int)pt.X, (int)pt.Y); + } + public static AvnPoint ToAvnPoint (this Point pt) { return new AvnPoint { X = pt.X, Y = pt.Y }; } + public static AvnPoint ToAvnPoint(this PixelPoint pt) + { + return new AvnPoint { X = pt.X, Y = pt.Y }; + } + public static AvnSize ToAvnSize (this Size size) { return new AvnSize { Height = size.Height, Width = size.Width }; @@ -31,5 +41,10 @@ namespace Avalonia.Native { return new Rect(rect.X, rect.Y, rect.Width, rect.Height); } + + public static PixelRect ToAvaloniaPixelRect(this AvnRect rect) + { + return new PixelRect((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height); + } } } diff --git a/src/Avalonia.Native/ScreenImpl.cs b/src/Avalonia.Native/ScreenImpl.cs index 079062c254..c1edd6c846 100644 --- a/src/Avalonia.Native/ScreenImpl.cs +++ b/src/Avalonia.Native/ScreenImpl.cs @@ -29,7 +29,10 @@ namespace Avalonia.Native { var screen = _native.GetScreen(i); - result[i] = new Screen(screen.Bounds.ToAvaloniaRect(), screen.WorkingArea.ToAvaloniaRect(), screen.Primary); + result[i] = new Screen( + screen.Bounds.ToAvaloniaPixelRect(), + screen.WorkingArea.ToAvaloniaPixelRect(), + screen.Primary); } return result; diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 629c91a2e8..3c8d8b597f 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -159,7 +159,7 @@ namespace Avalonia.Native void IAvnWindowBaseEvents.PositionChanged(AvnPoint position) { - _parent.PositionChanged?.Invoke(position.ToAvaloniaPoint()); + _parent.PositionChanged?.Invoke(position.ToAvaloniaPixelPoint()); } void IAvnWindowBaseEvents.RawMouseEvent(AvnRawMouseEventType type, uint timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta) @@ -275,20 +275,20 @@ namespace Avalonia.Native } - public Point Position + public PixelPoint Position { - get => _native.GetPosition().ToAvaloniaPoint(); + get => _native.GetPosition().ToAvaloniaPixelPoint(); set => _native.SetPosition(value.ToAvnPoint()); } - public Point PointToClient(Point point) + public Point PointToClient(PixelPoint point) { return _native.PointToClient(point.ToAvnPoint()).ToAvaloniaPoint(); } - public Point PointToScreen(Point point) + public PixelPoint PointToScreen(Point point) { - return _native.PointToScreen(point.ToAvnPoint()).ToAvaloniaPoint(); + return _native.PointToScreen(point.ToAvnPoint()).ToAvaloniaPixelPoint(); } public void Hide() @@ -320,7 +320,7 @@ namespace Avalonia.Native _native.Cursor = newCursor.Cursor; } - public Action PositionChanged { get; set; } + public Action PositionChanged { get; set; } public Action Input { get; set; } diff --git a/src/Avalonia.Visuals/Rendering/IRenderRoot.cs b/src/Avalonia.Visuals/Rendering/IRenderRoot.cs index 2b364e5d22..044911ca95 100644 --- a/src/Avalonia.Visuals/Rendering/IRenderRoot.cs +++ b/src/Avalonia.Visuals/Rendering/IRenderRoot.cs @@ -41,15 +41,15 @@ namespace Avalonia.Rendering /// /// Converts a point from screen to client coordinates. /// - /// The point in screen coordinates. + /// The point in screen device coordinates. /// The point in client coordinates. - Point PointToClient(Point point); + Point PointToClient(PixelPoint point); /// /// Converts a point from client to screen coordinates. /// /// The point in client coordinates. - /// The point in screen coordinates. - Point PointToScreen(Point point); + /// The point in screen device coordinates. + PixelPoint PointToScreen(Point point); } } diff --git a/src/Avalonia.Visuals/VisualExtensions.cs b/src/Avalonia.Visuals/VisualExtensions.cs index 7c5d011ce8..80ef41f5d4 100644 --- a/src/Avalonia.Visuals/VisualExtensions.cs +++ b/src/Avalonia.Visuals/VisualExtensions.cs @@ -18,10 +18,14 @@ namespace Avalonia /// The visual. /// The point in screen coordinates. /// The point in client coordinates. - public static Point PointToClient(this IVisual visual, Point point) + public static Point PointToClient(this IVisual visual, PixelPoint point) { - var p = GetRootAndPosition(visual); - return p.Item1.PointToClient(point - p.Item2); + var (root, offset) = GetRootAndPosition(visual); + var screenOffset = PixelPoint.FromPoint((Point)offset, root.RenderScaling); + var screenPoint = PixelPoint.FromPoint( + new Point(point.X - screenOffset.X, point.Y - screenOffset.Y), + root.RenderScaling); + return root.PointToClient(screenPoint); } /// @@ -30,7 +34,7 @@ namespace Avalonia /// The visual. /// The point in client coordinates. /// The point in screen coordinates. - public static Point PointToScreen(this IVisual visual, Point point) + public static PixelPoint PointToScreen(this IVisual visual, Point point) { var p = GetRootAndPosition(visual); return p.Item1.PointToScreen(point + p.Item2); diff --git a/src/Avalonia.X11/X11Screens.cs b/src/Avalonia.X11/X11Screens.cs index d775261de0..f2a0520c10 100644 --- a/src/Avalonia.X11/X11Screens.cs +++ b/src/Avalonia.X11/X11Screens.cs @@ -20,7 +20,7 @@ namespace Avalonia.X11 static unsafe X11Screen[] UpdateWorkArea(X11Info info, X11Screen[] screens) { - var rect = default(Rect); + var rect = default(PixelRect); foreach (var s in screens) { rect = rect.Union(s.Bounds); @@ -46,7 +46,7 @@ namespace Avalonia.X11 return screens; var pwa = (IntPtr*)prop; - var wa = new Rect(pwa[0].ToInt32(), pwa[1].ToInt32(), pwa[2].ToInt32(), pwa[3].ToInt32()); + var wa = new PixelRect(pwa[0].ToInt32(), pwa[1].ToInt32(), pwa[2].ToInt32(), pwa[3].ToInt32()); foreach (var s in screens) @@ -105,7 +105,7 @@ namespace Avalonia.X11 density *= _settings.GlobalScaleFactor; - var bounds = new Rect(mon.X, mon.Y, mon.Width, mon.Height); + var bounds = new PixelRect(mon.X, mon.Y, mon.Width, mon.Height); screens[c] = new X11Screen(bounds, mon.Primary != 0, name, @@ -130,12 +130,12 @@ namespace Avalonia.X11 Screens = UpdateWorkArea(info, new[] { - new X11Screen(new Rect(0, 0, geo.width, geo.height), true, "Default", null, + new X11Screen(new PixelRect(0, 0, geo.width, geo.height), true, "Default", null, settings.GlobalScaleFactor) }); } - Screens = new[] {new X11Screen(new Rect(0, 0, 1920, 1280), true, "Default", null, settings.GlobalScaleFactor)}; + Screens = new[] {new X11Screen(new PixelRect(0, 0, 1920, 1280), true, "Default", null, settings.GlobalScaleFactor)}; } public X11Screen[] Screens { get; } @@ -220,12 +220,12 @@ namespace Avalonia.X11 { public bool Primary { get; } public string Name { get; set; } - public Rect Bounds { get; set; } + public PixelRect Bounds { get; set; } public Size? PhysicalSize { get; set; } public double PixelDensity { get; set; } - public Rect WorkingArea { get; set; } + public PixelRect WorkingArea { get; set; } - public X11Screen(Rect bounds, bool primary, + public X11Screen(PixelRect bounds, bool primary, string name, Size? physicalSize, double? pixelDensity) { Primary = primary; diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index 710951fcab..14a9bc7c1a 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -24,12 +24,12 @@ namespace Avalonia.X11 private readonly X11Info _x11; private bool _invalidated; private XConfigureEvent? _configure; - private Point? _configurePoint; + private PixelPoint? _configurePoint; private bool _triggeredExpose; private IInputRoot _inputRoot; private readonly IMouseDevice _mouse; private readonly IKeyboardDevice _keyboard; - private Point? _position; + private PixelPoint? _position; private PixelSize _realSize; private IntPtr _handle; private IntPtr _xic; @@ -235,7 +235,7 @@ namespace Avalonia.X11 public Func Closing { get; set; } public Action WindowStateChanged { get; set; } public Action Closed { get; set; } - public Action PositionChanged { get; set; } + public Action PositionChanged { get; set; } public IRenderer CreateRenderer(IRenderRoot root) => new DeferredRenderer(root, AvaloniaLocator.Current.GetService()); @@ -321,13 +321,13 @@ namespace Avalonia.X11 var needEnqueue = (_configure == null); _configure = ev.ConfigureEvent; if (ev.ConfigureEvent.override_redirect || ev.ConfigureEvent.send_event) - _configurePoint = new Point(ev.ConfigureEvent.x, ev.ConfigureEvent.y); + _configurePoint = new PixelPoint(ev.ConfigureEvent.x, ev.ConfigureEvent.y); else { XTranslateCoordinates(_x11.Display, _handle, _x11.RootWindow, 0, 0, out var tx, out var ty, out _); - _configurePoint = new Point(tx, ty); + _configurePoint = new PixelPoint(tx, ty); } if (needEnqueue) Dispatcher.UIThread.Post(() => @@ -660,9 +660,11 @@ namespace Avalonia.X11 public void Hide() => XUnmapWindow(_x11.Display, _handle); - public Point PointToClient(Point point) => new Point((point.X - Position.X) / Scaling, (point.Y - Position.Y) / Scaling); + public Point PointToClient(PixelPoint point) => new Point((point.X - Position.X) / Scaling, (point.Y - Position.Y) / Scaling); - public Point PointToScreen(Point point) => new Point(point.X * Scaling + Position.X, point.Y * Scaling + Position.Y); + public PixelPoint PointToScreen(Point point) => new PixelPoint( + (int)(point.X * Scaling + Position.X), + (int)(point.Y * Scaling + Position.Y)); public void SetSystemDecorations(bool enabled) { @@ -716,7 +718,7 @@ namespace Avalonia.X11 public IPlatformHandle Handle { get; } - public Point Position + public PixelPoint Position { get => _position ?? default; set @@ -752,7 +754,7 @@ namespace Avalonia.X11 public IScreenImpl Screen => _platform.Screens; - public Size MaxClientSize => _platform.X11Screens.Screens.Select(s => s.Bounds.Size / s.PixelDensity) + public Size MaxClientSize => _platform.X11Screens.Screens.Select(s => s.Bounds.Size.ToSize(s.PixelDensity)) .OrderByDescending(x => x.Width + x.Height).FirstOrDefault(); diff --git a/src/Gtk/Avalonia.Gtk3/GtkScreen.cs b/src/Gtk/Avalonia.Gtk3/GtkScreen.cs index 7c28dd47b9..a2b4604130 100644 --- a/src/Gtk/Avalonia.Gtk3/GtkScreen.cs +++ b/src/Gtk/Avalonia.Gtk3/GtkScreen.cs @@ -6,7 +6,7 @@ namespace Avalonia.Gtk3 { private readonly int _screenId; - public GtkScreen(Rect bounds, Rect workingArea, bool primary, int screenId) : base(bounds, workingArea, primary) + public GtkScreen(PixelRect bounds, PixelRect workingArea, bool primary, int screenId) : base(bounds, workingArea, primary) { this._screenId = screenId; } @@ -21,4 +21,4 @@ namespace Avalonia.Gtk3 return (obj is GtkScreen screen) ? this._screenId == screen._screenId : base.Equals(obj); } } -} \ No newline at end of file +} diff --git a/src/Gtk/Avalonia.Gtk3/ScreenImpl.cs b/src/Gtk/Avalonia.Gtk3/ScreenImpl.cs index 97b5029219..9a19ed00e0 100644 --- a/src/Gtk/Avalonia.Gtk3/ScreenImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/ScreenImpl.cs @@ -27,8 +27,8 @@ namespace Avalonia.Gtk3 GdkRectangle workArea = new GdkRectangle(), geometry = new GdkRectangle(); Native.GdkScreenGetMonitorGeometry(screen, i, ref geometry); Native.GdkScreenGetMonitorWorkarea(screen, i, ref workArea); - Rect workAreaRect = new Rect(workArea.X, workArea.Y, workArea.Width, workArea.Height); - Rect geometryRect = new Rect(geometry.X, geometry.Y, geometry.Width, geometry.Height); + PixelRect workAreaRect = new PixelRect(workArea.X, workArea.Y, workArea.Width, workArea.Height); + PixelRect geometryRect = new PixelRect(geometry.X, geometry.Y, geometry.Width, geometry.Height); GtkScreen s = new GtkScreen(geometryRect, workAreaRect, i == primary, i); screens[i] = s; } diff --git a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs index 6d4544bfbd..c4697462d2 100644 --- a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs @@ -24,7 +24,7 @@ namespace Avalonia.Gtk3 private readonly EglGlPlatformSurface _egl; protected readonly List Disposables = new List(); private Size _lastSize; - private Point _lastPosition; + private PixelPoint _lastPosition; private double _lastScaling; private uint _lastKbdEvent; private uint _lastSmoothScrollEvent; @@ -383,7 +383,7 @@ namespace Avalonia.Gtk3 public Action Paint { get; set; } public Action Resized { get; set; } public Action ScalingChanged { get; set; } //TODO - public Action PositionChanged { get; set; } + public Action PositionChanged { get; set; } public void Activate() => Native.GtkWidgetActivate(GtkWidget); @@ -402,7 +402,7 @@ namespace Avalonia.Gtk3 Dispatcher.UIThread.Post(() => Input?.Invoke(args), DispatcherPriority.Input); } - public Point PointToClient(Point point) + public Point PointToClient(PixelPoint point) { int x, y; Native.GdkWindowGetOrigin(Native.GtkWidgetGetWindow(GtkWidget), out x, out y); @@ -410,11 +410,11 @@ namespace Avalonia.Gtk3 return new Point(point.X - x, point.Y - y); } - public Point PointToScreen(Point point) + public PixelPoint PointToScreen(Point point) { int x, y; Native.GdkWindowGetOrigin(Native.GtkWidgetGetWindow(GtkWidget), out x, out y); - return new Point(point.X + x, point.Y + y); + return new PixelPoint((int)(point.X + x), (int)(point.Y + y)); } public void SetCursor(IPlatformHandle cursor) @@ -490,13 +490,13 @@ namespace Avalonia.Gtk3 get; } = new ScreenImpl(); - public Point Position + public PixelPoint Position { get { int x, y; Native.GtkWindowGetPosition(GtkWidget, out x, out y); - return new Point(x, y); + return new PixelPoint(x, y); } set { Native.GtkWindowMove(GtkWidget, (int)value.X, (int)value.Y); } } diff --git a/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs b/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs index 968873abc0..6a63014e1a 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs @@ -51,9 +51,9 @@ namespace Avalonia.LinuxFramebuffer InputRoot = inputRoot; } - public Point PointToClient(Point point) => point; + public Point PointToClient(PixelPoint p) => p.ToPoint(1); - public Point PointToScreen(Point point) => point; + public PixelPoint PointToScreen(Point p) => PixelPoint.FromPoint(p, 1); public void SetCursor(IPlatformHandle cursor) { diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfInteropExtensions.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfInteropExtensions.cs index 44c4c84cd6..cbfc259eda 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfInteropExtensions.cs +++ b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfInteropExtensions.cs @@ -3,7 +3,9 @@ static class WpfInteropExtensions { public static System.Windows.Point ToWpfPoint(this Point pt) => new System.Windows.Point(pt.X, pt.Y); + public static System.Windows.Point ToWpfPoint(this PixelPoint pt) => new System.Windows.Point(pt.X, pt.Y); public static Point ToAvaloniaPoint(this System.Windows.Point pt) => new Point(pt.X, pt.Y); + public static PixelPoint ToAvaloniaPixelPoint(this System.Windows.Point pt) => new PixelPoint((int)pt.X, (int)pt.Y); public static System.Windows.Size ToWpfSize(this Size pt) => new System.Windows.Size(pt.Width, pt.Height); public static Size ToAvaloniaSize(this System.Windows.Size pt) => new Size(pt.Width, pt.Height); } diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs index b5fb158168..7005459487 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs +++ b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs @@ -135,9 +135,9 @@ namespace Avalonia.Win32.Interop.Wpf void ITopLevelImpl.SetInputRoot(IInputRoot inputRoot) => _inputRoot = inputRoot; - Point ITopLevelImpl.PointToClient(Point point) => PointFromScreen(point.ToWpfPoint()).ToAvaloniaPoint(); + Point ITopLevelImpl.PointToClient(PixelPoint point) => PointFromScreen(point.ToWpfPoint()).ToAvaloniaPoint(); - Point ITopLevelImpl.PointToScreen(Point point) => PointToScreen(point.ToWpfPoint()).ToAvaloniaPoint(); + PixelPoint ITopLevelImpl.PointToScreen(Point point) => PointToScreen(point.ToWpfPoint()).ToAvaloniaPixelPoint(); protected override void OnLostFocus(RoutedEventArgs e) => LostFocus?.Invoke(); diff --git a/src/Windows/Avalonia.Win32/OleDropTarget.cs b/src/Windows/Avalonia.Win32/OleDropTarget.cs index 7013931be9..28065566d0 100644 --- a/src/Windows/Avalonia.Win32/OleDropTarget.cs +++ b/src/Windows/Avalonia.Win32/OleDropTarget.cs @@ -177,7 +177,7 @@ namespace Avalonia.Win32 int x = (int)dragPoint; int y = (int)(dragPoint >> 32); - Point screenPt = new Point(x, y); + var screenPt = new PixelPoint(x, y); return _target.PointToClient(screenPt); } } diff --git a/src/Windows/Avalonia.Win32/ScreenImpl.cs b/src/Windows/Avalonia.Win32/ScreenImpl.cs index 5cfceb68b7..aa3b23eb50 100644 --- a/src/Windows/Avalonia.Win32/ScreenImpl.cs +++ b/src/Windows/Avalonia.Win32/ScreenImpl.cs @@ -31,10 +31,10 @@ namespace Avalonia.Win32 { RECT bounds = monitorInfo.rcMonitor; RECT workingArea = monitorInfo.rcWork; - Rect avaloniaBounds = new Rect(bounds.left, bounds.top, bounds.right - bounds.left, + PixelRect avaloniaBounds = new PixelRect(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top); - Rect avaloniaWorkArea = - new Rect(workingArea.left, workingArea.top, workingArea.right - workingArea.left, + PixelRect avaloniaWorkArea = + new PixelRect(workingArea.left, workingArea.top, workingArea.right - workingArea.left, workingArea.bottom - workingArea.top); screens[index] = new WinScreen(avaloniaBounds, avaloniaWorkArea, monitorInfo.dwFlags == 1, diff --git a/src/Windows/Avalonia.Win32/WinScreen.cs b/src/Windows/Avalonia.Win32/WinScreen.cs index 2f8dcb0f3e..e849800e62 100644 --- a/src/Windows/Avalonia.Win32/WinScreen.cs +++ b/src/Windows/Avalonia.Win32/WinScreen.cs @@ -7,7 +7,7 @@ namespace Avalonia.Win32 { private readonly IntPtr _hMonitor; - public WinScreen(Rect bounds, Rect workingArea, bool primary, IntPtr hMonitor) : base(bounds, workingArea, primary) + public WinScreen(PixelRect bounds, PixelRect workingArea, bool primary, IntPtr hMonitor) : base(bounds, workingArea, primary) { this._hMonitor = hMonitor; } @@ -22,4 +22,4 @@ namespace Avalonia.Win32 return (obj is WinScreen screen) ? this._hMonitor == screen._hMonitor : base.Equals(obj); } } -} \ No newline at end of file +} diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index f4eb0e2ea8..081a713e95 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -87,7 +87,7 @@ namespace Avalonia.Win32 public Action ScalingChanged { get; set; } - public Action PositionChanged { get; set; } + public Action PositionChanged { get; set; } public Action WindowStateChanged { get; set; } @@ -297,19 +297,19 @@ namespace Avalonia.Win32 UnmanagedMethods.InvalidateRect(_hwnd, ref r, false); } - public Point PointToClient(Point point) + public Point PointToClient(PixelPoint point) { var p = new UnmanagedMethods.POINT { X = (int)point.X, Y = (int)point.Y }; UnmanagedMethods.ScreenToClient(_hwnd, ref p); return new Point(p.X, p.Y) / Scaling; } - public Point PointToScreen(Point point) + public PixelPoint PointToScreen(Point point) { point *= Scaling; var p = new UnmanagedMethods.POINT { X = (int)point.X, Y = (int)point.Y }; UnmanagedMethods.ClientToScreen(_hwnd, ref p); - return new Point(p.X, p.Y); + return new PixelPoint(p.X, p.Y); } public void SetInputRoot(IInputRoot inputRoot) @@ -357,21 +357,21 @@ namespace Avalonia.Win32 #endif } - public Point Position + public PixelPoint Position { get { UnmanagedMethods.RECT rc; UnmanagedMethods.GetWindowRect(_hwnd, out rc); - return new Point(rc.left, rc.top); + return new PixelPoint(rc.left, rc.top); } set { UnmanagedMethods.SetWindowPos( Handle.Handle, IntPtr.Zero, - (int)value.X, - (int)value.Y, + value.X, + value.Y, 0, 0, UnmanagedMethods.SetWindowPosFlags.SWP_NOSIZE | UnmanagedMethods.SetWindowPosFlags.SWP_NOACTIVATE); @@ -661,7 +661,7 @@ namespace Avalonia.Win32 return IntPtr.Zero; case UnmanagedMethods.WindowsMessage.WM_MOVE: - PositionChanged?.Invoke(new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16))); + PositionChanged?.Invoke(new PixelPoint((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16))); return IntPtr.Zero; case UnmanagedMethods.WindowsMessage.WM_GETMINMAXINFO: @@ -785,9 +785,9 @@ namespace Avalonia.Win32 return new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16)) / Scaling; } - private Point PointFromLParam(IntPtr lParam) + private PixelPoint PointFromLParam(IntPtr lParam) { - return new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16)); + return new PixelPoint((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16)); } private Point ScreenToClient(Point point) diff --git a/src/iOS/Avalonia.iOS/TopLevelImpl.cs b/src/iOS/Avalonia.iOS/TopLevelImpl.cs index 1101f53222..83d10b8b44 100644 --- a/src/iOS/Avalonia.iOS/TopLevelImpl.cs +++ b/src/iOS/Avalonia.iOS/TopLevelImpl.cs @@ -68,9 +68,9 @@ namespace Avalonia.iOS public void SetInputRoot(IInputRoot inputRoot) => _inputRoot = inputRoot; - public Point PointToClient(Point point) => point; + public Point PointToClient(PixelPoint point) => point.ToPoint(1); - public Point PointToScreen(Point point) => point; + public PixelPoint PointToScreen(Point point) => PixelPoint.FromPoint(point, 1); public void SetCursor(IPlatformHandle cursor) { diff --git a/tests/Avalonia.Controls.UnitTests/ButtonTests.cs b/tests/Avalonia.Controls.UnitTests/ButtonTests.cs index 76f2898700..91b37596b7 100644 --- a/tests/Avalonia.Controls.UnitTests/ButtonTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ButtonTests.cs @@ -238,9 +238,9 @@ namespace Avalonia.Controls.UnitTests public void Invalidate(Rect rect) => throw new NotImplementedException(); - public Point PointToClient(Point point) => throw new NotImplementedException(); + public Point PointToClient(PixelPoint p) => throw new NotImplementedException(); - public Point PointToScreen(Point point) => throw new NotImplementedException(); + public PixelPoint PointToScreen(Point p) => throw new NotImplementedException(); } private void RaisePointerPressed(Button button, IMouseDevice device, int clickCount, MouseButton mouseButton) diff --git a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs index 66f0cc3a40..834c49ba6b 100644 --- a/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs @@ -160,7 +160,7 @@ namespace Avalonia.Controls.UnitTests private IDisposable Application() { - var screen = new Rect(new Point(), new Size(100, 100)); + var screen = new PixelRect(new PixelPoint(), new PixelSize(100, 100)); var screenImpl = new Mock(); screenImpl.Setup(x => x.ScreenCount).Returns(1); screenImpl.Setup(X => X.AllScreens).Returns( new[] { new Screen(screen, screen, true) }); diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs index ba4ccb0527..3ea32ed719 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs +++ b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs @@ -336,25 +336,11 @@ namespace Avalonia.Controls.UnitTests.Presenters public double LayoutScaling => 1; public ILayoutManager LayoutManager { get; } = new LayoutManager(); - public IRenderTarget CreateRenderTarget() - { - throw new NotImplementedException(); - } - - public void Invalidate(Rect rect) - { - throw new NotImplementedException(); - } - public Point PointToClient(Point point) - { - throw new NotImplementedException(); - } - - public Point PointToScreen(Point point) - { - throw new NotImplementedException(); - } + public IRenderTarget CreateRenderTarget() => throw new NotImplementedException(); + public void Invalidate(Rect rect) => throw new NotImplementedException(); + public Point PointToClient(PixelPoint p) => throw new NotImplementedException(); + public PixelPoint PointToScreen(Point p) => throw new NotImplementedException(); } private class TestItemsPresenter : ItemsPresenter diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs index 7187ea16da..9921a8de6c 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs +++ b/tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs @@ -1077,30 +1077,10 @@ namespace Avalonia.Controls.UnitTests.Presenters public ILayoutManager LayoutManager { get; } = new LayoutManager(); - public IRenderTarget CreateRenderTarget() - { - throw new NotImplementedException(); - } - - public void Invalidate(Rect rect) - { - throw new NotImplementedException(); - } - - public Point PointToClient(Point point) - { - throw new NotImplementedException(); - } - - public Point PointToScreen(Point point) - { - throw new NotImplementedException(); - } - - protected override Size MeasureOverride(Size availableSize) - { - return base.MeasureOverride(availableSize); - } + public IRenderTarget CreateRenderTarget() => throw new NotImplementedException(); + public void Invalidate(Rect rect) => throw new NotImplementedException(); + public Point PointToClient(PixelPoint p) => throw new NotImplementedException(); + public PixelPoint PointToScreen(Point p) => throw new NotImplementedException(); } private class TestItemsPresenter : ItemsPresenter diff --git a/tests/Avalonia.Controls.UnitTests/WindowTests.cs b/tests/Avalonia.Controls.UnitTests/WindowTests.cs index adf9bd9cec..c0b5342934 100644 --- a/tests/Avalonia.Controls.UnitTests/WindowTests.cs +++ b/tests/Avalonia.Controls.UnitTests/WindowTests.cs @@ -278,8 +278,8 @@ namespace Avalonia.Controls.UnitTests [Fact] public void Window_Should_Be_Centered_When_WindowStartupLocation_Is_CenterScreen() { - var screen1 = new Mock(new Rect(new Size(1920, 1080)), new Rect(new Size(1920, 1040)), true); - var screen2 = new Mock(new Rect(new Size(1366, 768)), new Rect(new Size(1366, 728)), false); + var screen1 = new Mock(new PixelRect(new PixelSize(1920, 1080)), new PixelRect(new PixelSize(1920, 1040)), true); + var screen2 = new Mock(new PixelRect(new PixelSize(1366, 768)), new PixelRect(new PixelSize(1366, 728)), false); var screens = new Mock(); screens.Setup(x => x.AllScreens).Returns(new Screen[] { screen1.Object, screen2.Object }); @@ -294,13 +294,13 @@ namespace Avalonia.Controls.UnitTests { var window = new Window(windowImpl.Object); window.WindowStartupLocation = WindowStartupLocation.CenterScreen; - window.Position = new Point(60, 40); + window.Position = new PixelPoint(60, 40); window.Show(); - var expectedPosition = new Point( - screen1.Object.WorkingArea.Size.Width / 2 - window.ClientSize.Width / 2, - screen1.Object.WorkingArea.Size.Height / 2 - window.ClientSize.Height / 2); + var expectedPosition = new PixelPoint( + (int)(screen1.Object.WorkingArea.Size.Width / 2 - window.ClientSize.Width / 2), + (int)(screen1.Object.WorkingArea.Size.Height / 2 - window.ClientSize.Height / 2)); Assert.Equal(window.Position, expectedPosition); } @@ -330,7 +330,7 @@ namespace Avalonia.Controls.UnitTests using (UnitTestApplication.Start(parentWindowServices)) { var parentWindow = new Window(); - parentWindow.Position = new Point(60, 40); + parentWindow.Position = new PixelPoint(60, 40); parentWindow.Show(); @@ -338,14 +338,14 @@ namespace Avalonia.Controls.UnitTests { var window = new Window(); window.WindowStartupLocation = WindowStartupLocation.CenterOwner; - window.Position = new Point(60, 40); + window.Position = new PixelPoint(60, 40); window.Owner = parentWindow; window.Show(); - var expectedPosition = new Point( - parentWindow.Position.X + parentWindow.ClientSize.Width / 2 - window.ClientSize.Width / 2, - parentWindow.Position.Y + parentWindow.ClientSize.Height / 2 - window.ClientSize.Height / 2); + var expectedPosition = new PixelPoint( + (int)(parentWindow.Position.X + parentWindow.ClientSize.Width / 2 - window.ClientSize.Width / 2), + (int)(parentWindow.Position.Y + parentWindow.ClientSize.Height / 2 - window.ClientSize.Height / 2)); Assert.Equal(window.Position, expectedPosition); } diff --git a/tests/Avalonia.UnitTests/TestRoot.cs b/tests/Avalonia.UnitTests/TestRoot.cs index 972b1d78c0..370ddba410 100644 --- a/tests/Avalonia.UnitTests/TestRoot.cs +++ b/tests/Avalonia.UnitTests/TestRoot.cs @@ -90,9 +90,9 @@ namespace Avalonia.UnitTests { } - public Point PointToClient(Point p) => p; + public Point PointToClient(PixelPoint p) => p.ToPoint(1); - public Point PointToScreen(Point p) => p; + public PixelPoint PointToScreen(Point p) => PixelPoint.FromPoint(p, 1); void INameScope.Register(string name, object element) { diff --git a/tests/Avalonia.UnitTests/TestTemplatedRoot.cs b/tests/Avalonia.UnitTests/TestTemplatedRoot.cs index 2d896435a3..5d42699d3f 100644 --- a/tests/Avalonia.UnitTests/TestTemplatedRoot.cs +++ b/tests/Avalonia.UnitTests/TestTemplatedRoot.cs @@ -57,9 +57,9 @@ namespace Avalonia.UnitTests throw new NotImplementedException(); } - public Point PointToClient(Point p) => p; + public Point PointToClient(PixelPoint p) => p.ToPoint(1); - public Point PointToScreen(Point p) => p; + public PixelPoint PointToScreen(Point p) => PixelPoint.FromPoint(p, 1); void INameScope.Register(string name, object element) {