From 4e51f4755ddbff539e2d1b43be637041c600a13e Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 13 Sep 2015 23:58:37 +0200 Subject: [PATCH 1/2] Use max platform window size in measure pass. Closes #133. --- src/Gtk/Perspex.Gtk/WindowImpl.cs | 9 +++++++++ src/Perspex.Controls/Platform/IWindowImpl.cs | 5 +++++ src/Perspex.Controls/Window.cs | 5 ++++- src/Windows/Perspex.Win32/WindowImpl.cs | 10 ++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 4247a3d853..5f88a9a1c3 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -57,6 +57,15 @@ namespace Perspex.Gtk set; } + public Size MaxWindowSize + { + get + { + // TODO: This should take into account things such as taskbar etc. + return new Size(Screen.Width, Screen.Height); + } + } + IPlatformHandle ITopLevelImpl.Handle => _windowHandle; public Action Activated { get; set; } diff --git a/src/Perspex.Controls/Platform/IWindowImpl.cs b/src/Perspex.Controls/Platform/IWindowImpl.cs index 934daa01a6..a05b7ed54d 100644 --- a/src/Perspex.Controls/Platform/IWindowImpl.cs +++ b/src/Perspex.Controls/Platform/IWindowImpl.cs @@ -10,6 +10,11 @@ namespace Perspex.Platform /// public interface IWindowImpl : ITopLevelImpl { + /// + /// Gets the maximum size of a window on the system. + /// + Size MaxWindowSize { get; } + /// /// Sets the title of the window. /// diff --git a/src/Perspex.Controls/Window.cs b/src/Perspex.Controls/Window.cs index e3934ad097..0484eab7b4 100644 --- a/src/Perspex.Controls/Window.cs +++ b/src/Perspex.Controls/Window.cs @@ -57,6 +57,8 @@ namespace Perspex.Controls private object _dialogResult; + private Size _maxPlatformWindowSize; + /// /// Initializes static members of the class. /// @@ -72,6 +74,7 @@ namespace Perspex.Controls public Window() : base(Locator.Current.GetService()) { + _maxPlatformWindowSize = this.PlatformImpl.MaxWindowSize; } /// @@ -193,7 +196,7 @@ namespace Perspex.Controls { var sizeToContent = SizeToContent; var size = ClientSize; - var desired = base.MeasureOverride(availableSize); + var desired = base.MeasureOverride(availableSize.Constrain(_maxPlatformWindowSize)); switch (sizeToContent) { diff --git a/src/Windows/Perspex.Win32/WindowImpl.cs b/src/Windows/Perspex.Win32/WindowImpl.cs index 75a03b832f..a80c92ca05 100644 --- a/src/Windows/Perspex.Win32/WindowImpl.cs +++ b/src/Windows/Perspex.Win32/WindowImpl.cs @@ -97,6 +97,16 @@ namespace Perspex.Win32 set { UnmanagedMethods.EnableWindow(_hwnd, value); } } + public Size MaxWindowSize + { + get + { + return new Size( + UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CXMAXTRACK), + UnmanagedMethods.GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYMAXTRACK)); + } + } + public void Activate() { UnmanagedMethods.SetActiveWindow(_hwnd); From a18bc4d913ce9f248adef7126005fed126df4bd1 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 16 Sep 2015 00:55:50 +0200 Subject: [PATCH 2/2] 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; } }