Forráskód Böngészése

Merge branch 'master' into parent-ambient-provider

Steven Kirk 7 éve
szülő
commit
7f3ff65668

+ 5 - 0
src/Avalonia.Controls/Platform/IWindowImpl.cs

@@ -45,6 +45,11 @@ namespace Avalonia.Platform
         /// </summary>
         void ShowTaskbarIcon(bool value);
 
+        /// <summary>
+        /// Enables or disables resizing of the window
+        /// </summary>
+        void CanResize(bool value);
+
         /// <summary>
         /// Gets or sets a method called before the underlying implementation is destroyed.
         /// Return true to prevent the underlying implementation from closing.

+ 14 - 0
src/Avalonia.Controls/Window.cs

@@ -95,6 +95,9 @@ namespace Avalonia.Controls
                 o => o.WindowStartupLocation,
                 (o, v) => o.WindowStartupLocation = v);
 
+        public static readonly StyledProperty<bool> CanResizeProperty =
+            AvaloniaProperty.Register<Window, bool>(nameof(CanResize), true);
+
         private readonly NameScope _nameScope = new NameScope();
         private object _dialogResult;
         private readonly Size _maxPlatformClientSize;
@@ -113,6 +116,8 @@ namespace Avalonia.Controls
             ShowInTaskbarProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.ShowTaskbarIcon((bool)e.NewValue));
 
             IconProperty.Changed.AddClassHandler<Window>((s, e) => s.PlatformImpl?.SetIcon(((WindowIcon)e.NewValue).PlatformImpl));
+
+            CanResizeProperty.Changed.AddClassHandler<Window>((w, e) => w.PlatformImpl?.CanResize((bool)e.NewValue));
         }
 
         /// <summary>
@@ -208,6 +213,15 @@ namespace Avalonia.Controls
             }
         }
 
+        /// <summary>
+        /// Enables or disables resizing of the window
+        /// </summary>
+        public bool CanResize
+        {
+            get { return GetValue(CanResizeProperty); }
+            set { SetValue(CanResizeProperty, value); }
+        }
+
         /// <summary>
         /// Gets or sets the icon of the window.
         /// </summary>

+ 4 - 0
src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

@@ -93,5 +93,9 @@ namespace Avalonia.DesignerSupport.Remote
         public void ShowTaskbarIcon(bool value)
         {
         }
+
+        public void CanResize(bool value)
+        {
+        }
     }
 }

+ 4 - 0
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@@ -95,6 +95,10 @@ namespace Avalonia.DesignerSupport.Remote
         public void ShowTaskbarIcon(bool value)
         {
         }
+
+        public void CanResize(bool value)
+        {
+        }
     }
 
     class ClipboardStub : IClipboard

+ 3 - 0
src/Gtk/Avalonia.Gtk3/Interop/Native.cs

@@ -115,6 +115,8 @@ namespace Avalonia.Gtk3.Interop
             [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
             public delegate void gtk_window_set_title(GtkWindow gtkWindow, Utf8Buffer title);
 
+            [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
+            public delegate void gtk_window_set_resizable(GtkWindow gtkWindow, bool resizable);
 
             [UnmanagedFunctionPointer(CallingConvention.Cdecl), GtkImport(GtkDll.Gtk)]
             public delegate void gtk_window_set_decorated(GtkWindow gtkWindow, bool decorated);
@@ -395,6 +397,7 @@ namespace Avalonia.Gtk3.Interop
         public static D.gdk_screen_get_monitor_geometry GdkScreenGetMonitorGeometry;
         public static D.gdk_screen_get_monitor_workarea GdkScreenGetMonitorWorkarea;
         public static D.gtk_window_set_decorated GtkWindowSetDecorated;
+        public static D.gtk_window_set_resizable GtkWindowSetResizable;
         public static D.gtk_window_set_skip_taskbar_hint GtkWindowSetSkipTaskbarHint;
         public static D.gtk_window_get_skip_taskbar_hint GtkWindowGetSkipTaskbarHint;
         public static D.gtk_window_set_skip_pager_hint GtkWindowSetSkipPagerHint;

+ 2 - 0
src/Gtk/Avalonia.Gtk3/WindowImpl.cs

@@ -61,6 +61,8 @@ namespace Avalonia.Gtk3
         }
 
         public void ShowTaskbarIcon(bool value) => Native.GtkWindowSetSkipTaskbarHint(GtkWidget, !value);
+
+        public void CanResize(bool value) => Native.GtkWindowSetResizable(GtkWidget, value);
         
 
         class EmptyDisposable : IDisposable

+ 15 - 3
src/OSX/Avalonia.MonoMac/WindowImpl.cs

@@ -9,6 +9,7 @@ namespace Avalonia.MonoMac
     class WindowImpl : WindowBaseImpl, IWindowImpl
     {
         public bool IsDecorated = true;
+        public bool IsResizable = true;
         public CGRect? UndecoratedLastUnmaximizedFrame;
 
         public WindowImpl()
@@ -76,10 +77,15 @@ namespace Avalonia.MonoMac
 
         protected override NSWindowStyle GetStyle()
         {
+            var windowStyle = NSWindowStyle.Borderless;
+
             if (IsDecorated)
-                return NSWindowStyle.Closable | NSWindowStyle.Resizable | NSWindowStyle.Miniaturizable |
-                       NSWindowStyle.Titled;
-            return NSWindowStyle.Borderless;
+                windowStyle |= NSWindowStyle.Closable | NSWindowStyle.Miniaturizable | NSWindowStyle.Titled;
+
+            if (IsResizable)
+                windowStyle |= NSWindowStyle.Resizable;
+
+            return windowStyle;
         }
 
         public void SetSystemDecorations(bool enabled)
@@ -88,6 +94,12 @@ namespace Avalonia.MonoMac
             UpdateStyle();
         }
 
+        public void CanResize(bool value)
+        {
+            IsResizable = value;
+            UpdateStyle();
+        }
+
         public void SetTitle(string title) => Window.Title = title;
 
         class ModalDisposable : IDisposable

+ 12 - 1
src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs

@@ -558,7 +558,18 @@ namespace Avalonia.Win32.Interop
         {
             DIB_RGB_COLORS = 0,     /* color table in RGBs */
             DIB_PAL_COLORS          /* color table in palette indices */
-        };
+        }
+
+        public enum WindowLongParam
+        {
+            GWL_WNDPROC = -4,
+            GWL_HINSTANCE = -6,
+            GWL_HWNDPARENT = -8,
+            GWL_ID = -12,
+            GWL_STYLE = -16,
+            GWL_EXSTYLE = -20,
+            GWL_USERDATA = -21
+        }
 
         [StructLayout(LayoutKind.Sequential)]
         public struct RGBQUAD

+ 36 - 11
src/Windows/Avalonia.Win32/WindowImpl.cs

@@ -31,6 +31,7 @@ namespace Avalonia.Win32
         private IInputRoot _owner;
         private bool _trackingMouse;
         private bool _decorated = true;
+        private bool _resizable = true;
         private double _scaling = 1;
         private WindowState _showWindowState;
         private FramebufferManager _framebuffer;
@@ -77,8 +78,8 @@ namespace Avalonia.Win32
         {
             get
             {
-                var style = UnmanagedMethods.GetWindowLong(_hwnd, -16);
-                var exStyle = UnmanagedMethods.GetWindowLong(_hwnd, -20);
+                var style = UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE);
+                var exStyle = UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE);
                 var padding = new UnmanagedMethods.RECT();
 
                 if (UnmanagedMethods.AdjustWindowRectEx(ref padding, style, false, exStyle))
@@ -235,13 +236,19 @@ namespace Avalonia.Win32
                 return;
             }
 
-            var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, -16);
+            var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE);
 
-            style |= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW;
+            var systemDecorationStyles = UnmanagedMethods.WindowStyles.WS_OVERLAPPED
+                | UnmanagedMethods.WindowStyles.WS_CAPTION
+                | UnmanagedMethods.WindowStyles.WS_SYSMENU
+                | UnmanagedMethods.WindowStyles.WS_MINIMIZEBOX
+                | UnmanagedMethods.WindowStyles.WS_MAXIMIZEBOX;
+
+            style |= systemDecorationStyles;
 
             if (!value)
             {
-                style ^= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW;
+                style ^= systemDecorationStyles;
             }
 
             UnmanagedMethods.RECT windowRect;
@@ -251,7 +258,7 @@ namespace Avalonia.Win32
             Rect newRect;
             var oldThickness = BorderThickness;
 
-            UnmanagedMethods.SetWindowLong(_hwnd, -16, (uint)style);
+            UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE, (uint)style);
 
             if (value)
             {
@@ -798,11 +805,11 @@ namespace Avalonia.Win32
 
         public void ShowTaskbarIcon(bool value)
         {
-            var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, -20);
-            
-            style &= ~(UnmanagedMethods.WindowStyles.WS_VISIBLE);   
+            var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE);
 
-            style |= UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW;   
+            style &= ~(UnmanagedMethods.WindowStyles.WS_VISIBLE);
+
+            style |= UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW;
             if (value)
                 style |= UnmanagedMethods.WindowStyles.WS_EX_APPWINDOW;
             else
@@ -813,9 +820,27 @@ namespace Avalonia.Win32
             {
                 //Toggle to make the styles stick
                 UnmanagedMethods.ShowWindow(_hwnd, ShowWindowCommand.Hide);
-                UnmanagedMethods.SetWindowLong(_hwnd, -20, (uint)style);
+                UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE, (uint)style);
                 UnmanagedMethods.ShowWindow(_hwnd, windowPlacement.ShowCmd);
             }
         }
+
+        public void CanResize(bool value)
+        {
+            if (value == _resizable)
+            {
+                return;
+            }
+
+            var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE);
+            
+            if (value)
+                style |= UnmanagedMethods.WindowStyles.WS_SIZEFRAME;
+            else
+                style &= ~(UnmanagedMethods.WindowStyles.WS_SIZEFRAME);
+            
+            UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE, (uint)style);
+            _resizable = value;
+        }
     }
 }