diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 0435a052ba..c9ed1bdfcd 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -75,6 +75,8 @@ namespace Perspex.Gtk } } + public double Scaling => 1; + IPlatformHandle ITopLevelImpl.Handle => this; [DllImport("libgdk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)] diff --git a/src/Perspex.Controls/Platform/ITopLevelImpl.cs b/src/Perspex.Controls/Platform/ITopLevelImpl.cs index 7c80b951a5..2bfb1f4a9a 100644 --- a/src/Perspex.Controls/Platform/ITopLevelImpl.cs +++ b/src/Perspex.Controls/Platform/ITopLevelImpl.cs @@ -22,6 +22,11 @@ namespace Perspex.Platform /// Size ClientSize { get; set; } + /// + /// Gets the scaling factor for the window. + /// + double Scaling { get; } + /// /// Gets the platform window handle. /// diff --git a/src/Perspex.Controls/Platform/PlatformManager.cs b/src/Perspex.Controls/Platform/PlatformManager.cs index 6cec6cfadf..400c77d559 100644 --- a/src/Perspex.Controls/Platform/PlatformManager.cs +++ b/src/Perspex.Controls/Platform/PlatformManager.cs @@ -39,9 +39,6 @@ namespace Perspex.Controls.Platform _designerScalingFactor = factor; } - static double RenderScalingFactor => (GetSettings()?.RenderScalingFactor ?? 1)*_designerScalingFactor; - static double LayoutScalingFactor => (GetSettings()?.LayoutScalingFactor ?? 1) * _designerScalingFactor; - class RenderTargetDecorator : IRenderTarget { private readonly IRenderTarget _target; @@ -62,7 +59,7 @@ namespace Perspex.Controls.Platform { var cs = _window.ClientSize; var ctx = _target.CreateDrawingContext(); - var factor = RenderScalingFactor; + var factor = _window.Scaling; if (factor != 1) { ctx.PushPostTransform(Matrix.CreateScale(factor, factor)); @@ -79,7 +76,6 @@ namespace Perspex.Controls.Platform private readonly IPopupImpl _popup; public ITopLevelImpl TopLevel => _tl; - double ScalingFactor => LayoutScalingFactor; public WindowDecorator(ITopLevelImpl tl) { @@ -93,12 +89,12 @@ namespace Perspex.Controls.Platform private void OnResized(Size size) { - Resized?.Invoke(size/ScalingFactor); + Resized?.Invoke(size/Scaling); } private void OnPaint(Rect rc) { - var f = ScalingFactor; + var f = Scaling; Paint?.Invoke(new Rect(rc.X/f, rc.Y/f, rc.Width/f, rc.Height/f)); } @@ -106,31 +102,31 @@ namespace Perspex.Controls.Platform { var mouseEvent = obj as RawMouseEventArgs; if (mouseEvent != null) - mouseEvent.Position /= ScalingFactor; + mouseEvent.Position /= Scaling; //TODO: Transform event coordinates Input?.Invoke(obj); } public Point PointToScreen(Point point) { - return _tl.PointToScreen(point*ScalingFactor)/ScalingFactor; + return _tl.PointToScreen(point*Scaling)/Scaling; } public void Invalidate(Rect rc) { - var f = ScalingFactor; + var f = Scaling; _tl.Invalidate(new Rect(rc.X*f, rc.Y*f, (rc.Width + 1)*f, (rc.Height + 1)*f)); } public Size ClientSize { - get { return _tl.ClientSize/ScalingFactor; } - set { _tl.ClientSize = value*ScalingFactor; } + get { return _tl.ClientSize/Scaling; } + set { _tl.ClientSize = value*Scaling; } } - public Size MaxClientSize => _window.MaxClientSize/ScalingFactor; - + public Size MaxClientSize => _window.MaxClientSize/Scaling; + public double Scaling => _tl.Scaling; public Action Input { get; set; } public Action Paint { get; set; } public Action Resized { get; set; } diff --git a/src/Perspex.Controls/TopLevel.cs b/src/Perspex.Controls/TopLevel.cs index e019301609..92cc25f51a 100644 --- a/src/Perspex.Controls/TopLevel.cs +++ b/src/Perspex.Controls/TopLevel.cs @@ -198,6 +198,9 @@ namespace Perspex.Controls /// Size ILayoutRoot.MaxClientSize => Size.Infinity; + /// + double ILayoutRoot.LayoutScaling => PlatformImpl.Scaling; + IStyleHost IStyleHost.StylingParent { get { return PerspexLocator.Current.GetService(); } diff --git a/src/Perspex.Layout/ILayoutRoot.cs b/src/Perspex.Layout/ILayoutRoot.cs index ea2083b0d0..e1a6ebe727 100644 --- a/src/Perspex.Layout/ILayoutRoot.cs +++ b/src/Perspex.Layout/ILayoutRoot.cs @@ -17,5 +17,10 @@ namespace Perspex.Layout /// The maximum client size available. /// Size MaxClientSize { get; } + + /// + /// The scaling factor to use in layout. + /// + double LayoutScaling { get; } } } diff --git a/src/Perspex.Layout/Layoutable.cs b/src/Perspex.Layout/Layoutable.cs index ce47d68e4c..119622bf4b 100644 --- a/src/Perspex.Layout/Layoutable.cs +++ b/src/Perspex.Layout/Layoutable.cs @@ -671,9 +671,9 @@ namespace Perspex.Layout return new Size(Math.Max(size.Width, 0), Math.Max(size.Height, 0)); } - private static double GetLayoutScale() + private double GetLayoutScale() { - return PerspexLocator.Current.GetService()?.LayoutScalingFactor ?? 1.0; + return (VisualRoot as ILayoutRoot)?.LayoutScaling ?? 1.0; } } } diff --git a/src/Perspex.SceneGraph/Platform/IPlatformSettings.cs b/src/Perspex.SceneGraph/Platform/IPlatformSettings.cs index 9b680a388d..d269d01c1c 100644 --- a/src/Perspex.SceneGraph/Platform/IPlatformSettings.cs +++ b/src/Perspex.SceneGraph/Platform/IPlatformSettings.cs @@ -10,9 +10,5 @@ namespace Perspex.Platform Size DoubleClickSize { get; } TimeSpan DoubleClickTime { get; } - - double RenderScalingFactor { get; } - - double LayoutScalingFactor { get; } } } diff --git a/src/Windows/Perspex.Win32/WindowImpl.cs b/src/Windows/Perspex.Win32/WindowImpl.cs index 49383c10e3..f003c9a5a9 100644 --- a/src/Windows/Perspex.Win32/WindowImpl.cs +++ b/src/Windows/Perspex.Win32/WindowImpl.cs @@ -103,6 +103,8 @@ namespace Perspex.Win32 } } + public double Scaling => 1; + public IPlatformHandle Handle { get; diff --git a/tests/Perspex.Controls.UnitTests/ControlTests.cs b/tests/Perspex.Controls.UnitTests/ControlTests.cs index 30c1aafc38..2ef3cdd9d4 100644 --- a/tests/Perspex.Controls.UnitTests/ControlTests.cs +++ b/tests/Perspex.Controls.UnitTests/ControlTests.cs @@ -174,6 +174,8 @@ namespace Perspex.Controls.UnitTests get { throw new NotImplementedException(); } } + public double LayoutScaling => 1; + public Point TranslatePointToScreen(Point p) { throw new NotImplementedException(); diff --git a/tests/Perspex.Controls.UnitTests/TestRoot.cs b/tests/Perspex.Controls.UnitTests/TestRoot.cs index cc911c8b90..9b15e58f0d 100644 --- a/tests/Perspex.Controls.UnitTests/TestRoot.cs +++ b/tests/Perspex.Controls.UnitTests/TestRoot.cs @@ -23,6 +23,8 @@ namespace Perspex.Controls.UnitTests get { throw new NotImplementedException(); } } + public double LayoutScaling => 1; + public IRenderQueueManager RenderQueueManager => null; public Point TranslatePointToScreen(Point p) diff --git a/tests/Perspex.Controls.UnitTests/TopLevelTests.cs b/tests/Perspex.Controls.UnitTests/TopLevelTests.cs index 9999630b85..86b86f1708 100644 --- a/tests/Perspex.Controls.UnitTests/TopLevelTests.cs +++ b/tests/Perspex.Controls.UnitTests/TopLevelTests.cs @@ -96,6 +96,7 @@ namespace Perspex.Controls.UnitTests var impl = new Mock(); impl.SetupProperty(x => x.ClientSize); impl.SetupProperty(x => x.Resized); + impl.SetupGet(x => x.Scaling).Returns(1); var target = new TestTopLevel(impl.Object) { @@ -121,9 +122,9 @@ namespace Perspex.Controls.UnitTests RegisterServices(); PerspexLocator.CurrentMutable.Bind().ToConstant(new LayoutManager()); - var impl = new Mock(); + var impl = Mock.Of(x => x.Scaling == 1); - var target = new TestTopLevel(impl.Object) + var target = new TestTopLevel(impl) { Template = CreateTemplate(), Content = new TextBlock @@ -135,7 +136,7 @@ namespace Perspex.Controls.UnitTests LayoutManager.Instance.ExecuteInitialLayoutPass(target); - impl.VerifySet(x => x.ClientSize = new Size(321, 432)); + Mock.Get(impl).VerifySet(x => x.ClientSize = new Size(321, 432)); } } diff --git a/tests/Perspex.Controls.UnitTests/WindowingPlatformMock.cs b/tests/Perspex.Controls.UnitTests/WindowingPlatformMock.cs index 989cb5f784..6e021fdae8 100644 --- a/tests/Perspex.Controls.UnitTests/WindowingPlatformMock.cs +++ b/tests/Perspex.Controls.UnitTests/WindowingPlatformMock.cs @@ -17,7 +17,7 @@ namespace Perspex.Controls.UnitTests public IWindowImpl CreateWindow() { - return _windowImpl?.Invoke() ?? new Mock().Object; + return _windowImpl?.Invoke() ?? Mock.Of(x => x.Scaling == 1); } public IWindowImpl CreateEmbeddableWindow() @@ -25,6 +25,6 @@ namespace Perspex.Controls.UnitTests throw new NotImplementedException(); } - public IPopupImpl CreatePopup() => _popupImpl?.Invoke() ?? new Mock().Object; + public IPopupImpl CreatePopup() => _popupImpl?.Invoke() ?? Mock.Of(x => x.Scaling == 1); } } \ No newline at end of file diff --git a/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs b/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs index b3ec813f75..6df4fa1f89 100644 --- a/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs +++ b/tests/Perspex.Layout.UnitTests/FullLayoutTests.cs @@ -141,6 +141,7 @@ namespace Perspex.Layout.UnitTests windowImpl.SetupProperty(x => x.ClientSize); windowImpl.Setup(x => x.MaxClientSize).Returns(new Size(1024, 1024)); + windowImpl.SetupGet(x => x.Scaling).Returns(1); PerspexLocator.CurrentMutable .Bind().ToConstant(new AssetLoader()) diff --git a/tests/Perspex.Layout.UnitTests/TestLayoutRoot.cs b/tests/Perspex.Layout.UnitTests/TestLayoutRoot.cs index d186b07169..2c0c1b3b8b 100644 --- a/tests/Perspex.Layout.UnitTests/TestLayoutRoot.cs +++ b/tests/Perspex.Layout.UnitTests/TestLayoutRoot.cs @@ -19,5 +19,6 @@ namespace Perspex.Layout.UnitTests } public Size MaxClientSize => Size.Infinity; + public double LayoutScaling => 1; } } diff --git a/tests/Perspex.LeakTests/TestApp.cs b/tests/Perspex.LeakTests/TestApp.cs index d95d249f7d..0484af5065 100644 --- a/tests/Perspex.LeakTests/TestApp.cs +++ b/tests/Perspex.LeakTests/TestApp.cs @@ -19,7 +19,7 @@ namespace Perspex.LeakTests RegisterServices(); var fixture = new Fixture().Customize(new AutoMoqCustomization()); - var windowImpl = new Mock(); + var windowImpl = Mock.Of(x => x.Scaling == 1); var renderInterface = fixture.Create(); var threadingInterface = Mock.Of(x => x.CurrentThreadIsLoopThread == true); @@ -31,7 +31,7 @@ namespace Perspex.LeakTests .Bind().ToConstant(renderInterface) .Bind().ToConstant(threadingInterface) .Bind().ToConstant(new Mock().Object) - .Bind().ToConstant(new WindowingPlatformMock(() => windowImpl.Object)); + .Bind().ToConstant(new WindowingPlatformMock(() => windowImpl)); Styles = new DefaultTheme(); } diff --git a/tests/Perspex.Styling.UnitTests/TestRoot.cs b/tests/Perspex.Styling.UnitTests/TestRoot.cs index cc3deed060..6c906184c5 100644 --- a/tests/Perspex.Styling.UnitTests/TestRoot.cs +++ b/tests/Perspex.Styling.UnitTests/TestRoot.cs @@ -26,6 +26,8 @@ namespace Perspex.Styling.UnitTests get { throw new NotImplementedException(); } } + public double LayoutScaling => 1; + public Point TranslatePointToScreen(Point p) { return new Point();