From bd33b3076b4eea33731dcf9a8eedf374aa2a1aef Mon Sep 17 00:00:00 2001 From: Stano Turza Date: Tue, 17 Apr 2018 14:35:08 +0200 Subject: [PATCH] Fix Win32 window size constraints fixes + revert testing changes --- .../Platform/IWindowBaseImpl.cs | 24 +++++++++++++-- src/Avalonia.Controls/WindowBase.cs | 9 +++++- .../Remote/PreviewerWindowImpl.cs | 8 +++++ src/Avalonia.DesignerSupport/Remote/Stubs.cs | 8 +++++ src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs | 8 +++++ src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs | 8 +++++ .../Interop/UnmanagedMethods.cs | 10 +++++++ src/Windows/Avalonia.Win32/WindowImpl.cs | 29 ++++++++++++++++++- 8 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs b/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs index 0a01cf3df4..f043371e9d 100644 --- a/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs +++ b/src/Avalonia.Controls/Platform/IWindowBaseImpl.cs @@ -55,7 +55,7 @@ namespace Avalonia.Platform /// Gets the platform window handle. /// IPlatformHandle Handle { get; } - + /// /// Gets the maximum size of a window on the system. /// @@ -65,7 +65,27 @@ namespace Avalonia.Platform /// Sets the client size of the toplevel. /// void Resize(Size clientSize); - + + /// + /// Minimum width of the window. + /// + double MinWidth { get; set; } + + /// + /// Maximum width of the window. + /// + double MaxWidth { get; set; } + + /// + /// Minimum height of the window. + /// + double MinHeight { get; set; } + + /// + /// Maximum height of the window. + /// + double MaxHeight { get; set; } + /// /// Gets platform specific display information /// diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs index 50068d280d..16fc8117d5 100644 --- a/src/Avalonia.Controls/WindowBase.cs +++ b/src/Avalonia.Controls/WindowBase.cs @@ -197,7 +197,14 @@ namespace Avalonia.Controls { using (BeginAutoSizing()) { - PlatformImpl?.Resize(finalSize); + if (PlatformImpl != null) + { + PlatformImpl.MinHeight = MinHeight; + PlatformImpl.MaxHeight = MaxHeight; + PlatformImpl.MinWidth = MinWidth; + PlatformImpl.MaxWidth = MaxWidth; + PlatformImpl.Resize(finalSize); + } } return base.ArrangeOverride(PlatformImpl?.ClientSize ?? default(Size)); diff --git a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs index fc9541abb7..703f5ec5c8 100644 --- a/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs +++ b/src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs @@ -67,6 +67,14 @@ namespace Avalonia.DesignerSupport.Remote RenderIfNeeded(); } + public double MinWidth { get; set; } + + public double MaxWidth { get; set; } + + public double MinHeight { get; set; } + + public double MaxHeight { get; set; } + public IScreenImpl Screen { get; } = new ScreenStub(); public void Activate() diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs index 560425286e..6dd207178d 100644 --- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs +++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs @@ -78,6 +78,14 @@ namespace Avalonia.DesignerSupport.Remote public IScreenImpl Screen { get; } = new ScreenStub(); + public double MinWidth { get; set; } + + public double MaxWidth { get; set; } + + public double MinHeight { get; set; } + + public double MaxHeight { get; set; } + public void SetTitle(string title) { } diff --git a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs index a42c8a19b9..768b1500af 100644 --- a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs @@ -341,6 +341,14 @@ namespace Avalonia.Gtk3 } } + public double MinWidth { get; set; } + + public double MaxWidth { get; set; } + + public double MinHeight { get; set; } + + public double MaxHeight { get; set; } + public IMouseDevice MouseDevice => Gtk3Platform.Mouse; public double Scaling => LastKnownScaleFactor = (int) (Native.GtkWidgetGetScaleFactor?.Invoke(GtkWidget) ?? 1); diff --git a/src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs b/src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs index e5ba285f4f..0b64aae36b 100644 --- a/src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs +++ b/src/OSX/Avalonia.MonoMac/WindowBaseImpl.cs @@ -161,6 +161,14 @@ namespace Avalonia.MonoMac Position = pos; } + public double MinWidth { get; set; } + + public double MaxWidth { get; set; } + + public double MinHeight { get; set; } + + public double MaxHeight { get; set; } + public IScreenImpl Screen { get; diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index aa86ab0f8d..b679d746f3 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -615,6 +615,16 @@ namespace Avalonia.Win32.Interop public uint[] cols; } + [StructLayout(LayoutKind.Sequential)] + public struct MINMAXINFO + { + public POINT ptReserved; + public POINT ptMaxSize; + public POINT ptMaxPosition; + public POINT ptMinTrackSize; + public POINT ptMaxTrackSize; + } + public const int SizeOf_BITMAPINFOHEADER = 40; [DllImport("user32.dll")] diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index bb3c4cf6e6..73d8228bab 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -102,6 +102,14 @@ namespace Avalonia.Win32 } } + public double MinWidth { get; set; } + + public double MaxWidth { get; set; } + + public double MinHeight { get; set; } + + public double MaxHeight { get; set; } + public IScreenImpl Screen { get; @@ -611,7 +619,26 @@ namespace Avalonia.Win32 case UnmanagedMethods.WindowsMessage.WM_MOVE: PositionChanged?.Invoke(new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16))); return IntPtr.Zero; - + + case UnmanagedMethods.WindowsMessage.WM_GETMINMAXINFO: + + MINMAXINFO mmi = Marshal.PtrToStructure(lParam); + + if (MinWidth > 0) + mmi.ptMinTrackSize.X = (int)((MinWidth * Scaling) + BorderThickness.Left + BorderThickness.Right); + + if (MinHeight > 0) + mmi.ptMinTrackSize.Y = (int)((MinHeight * Scaling) + BorderThickness.Top + BorderThickness.Bottom); + + if (!Double.IsInfinity(MaxWidth) && MaxWidth > 0) + mmi.ptMaxTrackSize.X = (int)((MaxWidth * Scaling) + BorderThickness.Left + BorderThickness.Right); + + if (!Double.IsInfinity(MaxHeight) && MaxHeight > 0) + mmi.ptMaxTrackSize.Y = (int)((MaxHeight * Scaling) + BorderThickness.Top + BorderThickness.Bottom); + + Marshal.StructureToPtr(mmi, lParam, true); + return IntPtr.Zero; + case UnmanagedMethods.WindowsMessage.WM_DISPLAYCHANGE: (Screen as ScreenImpl)?.InvalidateScreensCache(); return IntPtr.Zero;