From a18bc4d913ce9f248adef7126005fed126df4bd1 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 16 Sep 2015 00:55:50 +0200 Subject: [PATCH] Convert max window size to client size. --- src/Gtk/Perspex.Gtk/WindowImpl.cs | 5 +- src/Perspex.Controls/Platform/IWindowImpl.cs | 2 +- src/Perspex.Controls/Window.cs | 6 +-- src/Perspex.SceneGraph/Thickness.cs | 26 +++++++++++ src/Windows/Perspex.Win32/WindowImpl.cs | 49 +++++++++++++------- 5 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 5f88a9a1c3..9b98343435 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -57,11 +57,12 @@ namespace Perspex.Gtk set; } - public Size MaxWindowSize + public Size MaxClientSize { get { - // TODO: This should take into account things such as taskbar etc. + // TODO: This should take into account things such as taskbar and window border + // thickness etc. return new Size(Screen.Width, Screen.Height); } } diff --git a/src/Perspex.Controls/Platform/IWindowImpl.cs b/src/Perspex.Controls/Platform/IWindowImpl.cs index a05b7ed54d..58ef5281b0 100644 --- a/src/Perspex.Controls/Platform/IWindowImpl.cs +++ b/src/Perspex.Controls/Platform/IWindowImpl.cs @@ -13,7 +13,7 @@ namespace Perspex.Platform /// /// Gets the maximum size of a window on the system. /// - Size MaxWindowSize { get; } + Size MaxClientSize { get; } /// /// Sets the title of the window. diff --git a/src/Perspex.Controls/Window.cs b/src/Perspex.Controls/Window.cs index 0484eab7b4..fb3fee2587 100644 --- a/src/Perspex.Controls/Window.cs +++ b/src/Perspex.Controls/Window.cs @@ -57,7 +57,7 @@ namespace Perspex.Controls private object _dialogResult; - private Size _maxPlatformWindowSize; + private Size _maxPlatformClientSize; /// /// Initializes static members of the class. @@ -74,7 +74,7 @@ namespace Perspex.Controls public Window() : base(Locator.Current.GetService()) { - _maxPlatformWindowSize = this.PlatformImpl.MaxWindowSize; + _maxPlatformClientSize = this.PlatformImpl.MaxClientSize; } /// @@ -196,7 +196,7 @@ namespace Perspex.Controls { var sizeToContent = SizeToContent; var size = ClientSize; - var desired = base.MeasureOverride(availableSize.Constrain(_maxPlatformWindowSize)); + var desired = base.MeasureOverride(availableSize.Constrain(_maxPlatformClientSize)); switch (sizeToContent) { diff --git a/src/Perspex.SceneGraph/Thickness.cs b/src/Perspex.SceneGraph/Thickness.cs index 9861342e2b..693dd97340 100644 --- a/src/Perspex.SceneGraph/Thickness.cs +++ b/src/Perspex.SceneGraph/Thickness.cs @@ -138,6 +138,32 @@ namespace Perspex a.Bottom + b.Bottom); } + /// + /// Adds a Thickness to a Size. + /// + /// The size. + /// The thickness. + /// The equality. + public static Size operator +(Size size, Thickness thickness) + { + return new Size( + size.Width + thickness.Left + thickness.Right, + size.Height + thickness.Top + thickness.Bottom); + } + + /// + /// Subtracts a Thickness from a Size. + /// + /// The size. + /// The thickness. + /// The equality. + public static Size operator -(Size size, Thickness thickness) + { + return new Size( + size.Width - (thickness.Left + thickness.Right), + size.Height - (thickness.Top + thickness.Bottom)); + } + /// /// Parses a string. /// diff --git a/src/Windows/Perspex.Win32/WindowImpl.cs b/src/Windows/Perspex.Win32/WindowImpl.cs index a80c92ca05..4c9847087d 100644 --- a/src/Windows/Perspex.Win32/WindowImpl.cs +++ b/src/Windows/Perspex.Win32/WindowImpl.cs @@ -53,6 +53,25 @@ namespace Perspex.Win32 public Action Resized { get; set; } + public Thickness BorderThickness + { + get + { + var style = UnmanagedMethods.GetWindowLong(_hwnd, -16); + var exStyle = UnmanagedMethods.GetWindowLong(_hwnd, -20); + var padding = new UnmanagedMethods.RECT(); + + if (UnmanagedMethods.AdjustWindowRectEx(ref padding, style, false, exStyle)) + { + return new Thickness(-padding.left, -padding.top, padding.right, padding.bottom); + } + else + { + throw new Win32Exception(); + } + } + } + public Size ClientSize { get @@ -66,21 +85,16 @@ namespace Perspex.Win32 { if (value != ClientSize) { - var style = UnmanagedMethods.GetWindowLong(_hwnd, -16); - var exStyle = UnmanagedMethods.GetWindowLong(_hwnd, -20); - var padding = new UnmanagedMethods.RECT(); - - if (UnmanagedMethods.AdjustWindowRectEx(ref padding, style, false, exStyle)) - { - UnmanagedMethods.SetWindowPos( - _hwnd, - IntPtr.Zero, - 0, - 0, - -padding.left + padding.right + (int)value.Width, - -padding.top + padding.bottom + (int)value.Height, - UnmanagedMethods.SetWindowPosFlags.SWP_RESIZE); - } + value += BorderThickness; + + UnmanagedMethods.SetWindowPos( + _hwnd, + IntPtr.Zero, + 0, + 0, + (int)value.Width, + (int)value.Height, + UnmanagedMethods.SetWindowPosFlags.SWP_RESIZE); } } } @@ -97,13 +111,14 @@ namespace Perspex.Win32 set { UnmanagedMethods.EnableWindow(_hwnd, value); } } - public Size MaxWindowSize + public Size MaxClientSize { get { return new Size( UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CXMAXTRACK), - UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYMAXTRACK)); + UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYMAXTRACK)) + - BorderThickness; } }