From ec2a319049c8f033fc38c4122f1778b58dd52aee Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Sat, 12 Dec 2015 07:38:29 +0300 Subject: [PATCH] Implemented BeginResizeDrag --- .../Platform/SkiaPlatform/WindowImpl.cs | 6 ++++ src/Gtk/Perspex.Gtk/WindowImpl.cs | 9 ++++++ src/Perspex.Controls/Perspex.Controls.csproj | 1 + .../Platform/ITopLevelImpl.cs | 9 +++++- .../Platform/PlatformManager.cs | 1 + src/Perspex.Controls/TopLevel.cs | 6 ++++ src/Perspex.Controls/WindowEdge.cs | 17 +++++++++++ .../Perspex.Win32/Interop/UnmanagedMethods.cs | 28 +++++++++++++++++++ src/Windows/Perspex.Win32/WindowImpl.cs | 20 ++++++++++++- src/iOS/Perspex.iOS/PerspexView.cs | 6 ++++ 10 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/Perspex.Controls/WindowEdge.cs diff --git a/src/Android/Perspex.Android/Platform/SkiaPlatform/WindowImpl.cs b/src/Android/Perspex.Android/Platform/SkiaPlatform/WindowImpl.cs index 1697295198..14bd084a37 100644 --- a/src/Android/Perspex.Android/Platform/SkiaPlatform/WindowImpl.cs +++ b/src/Android/Perspex.Android/Platform/SkiaPlatform/WindowImpl.cs @@ -9,6 +9,7 @@ using Perspex.Input.Raw; using Perspex.Platform; using Perspex.Skia.Android; using System; +using Perspex.Controls; namespace Perspex.Android.Platform.SkiaPlatform { @@ -131,6 +132,11 @@ namespace Perspex.Android.Platform.SkiaPlatform //Not supported } + public void BeginResizeDrag(WindowEdge edge) + { + //Not supported + } + public IDisposable ShowDialog() { throw new NotImplementedException(); diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 67d075add8..01054ae50b 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -11,6 +11,7 @@ using Perspex.Platform; using Perspex.Input; using Perspex.Threading; using Action = System.Action; +using WindowEdge = Perspex.Controls.WindowEdge; namespace Perspex.Gtk { @@ -170,6 +171,14 @@ namespace Perspex.Gtk BeginMoveDrag(1, x, y, 0); } + public void BeginResizeDrag(WindowEdge edge) + { + int x, y; + ModifierType mod; + Screen.RootWindow.GetPointer(out x, out y, out mod); + BeginResizeDrag((Gdk.WindowEdge) (int) edge, 1, x, y, 0); + } + public IDisposable ShowDialog() { Modal = true; diff --git a/src/Perspex.Controls/Perspex.Controls.csproj b/src/Perspex.Controls/Perspex.Controls.csproj index f9a4a3ad84..5a8557da6b 100644 --- a/src/Perspex.Controls/Perspex.Controls.csproj +++ b/src/Perspex.Controls/Perspex.Controls.csproj @@ -171,6 +171,7 @@ + diff --git a/src/Perspex.Controls/Platform/ITopLevelImpl.cs b/src/Perspex.Controls/Platform/ITopLevelImpl.cs index ade7aab3bd..0a11566c5a 100644 --- a/src/Perspex.Controls/Platform/ITopLevelImpl.cs +++ b/src/Perspex.Controls/Platform/ITopLevelImpl.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using Perspex.Controls; using Perspex.Input; using Perspex.Input.Raw; @@ -90,8 +91,14 @@ namespace Perspex.Platform void Show(); /// - /// Starts moving a window with left button being held. Should be called from left mouse button press event handler + /// Starts moving a window with left button being held. Should be called from left mouse button press event handler. /// void BeginMoveDrag(); + + /// + /// Starts resizing a window. This function is used if an application has window resizing controls. + /// Should be called from left mouse button press event handler + /// + void BeginResizeDrag(WindowEdge edge); } } diff --git a/src/Perspex.Controls/Platform/PlatformManager.cs b/src/Perspex.Controls/Platform/PlatformManager.cs index 1e7b5cc755..fc582ab45d 100644 --- a/src/Perspex.Controls/Platform/PlatformManager.cs +++ b/src/Perspex.Controls/Platform/PlatformManager.cs @@ -175,6 +175,7 @@ namespace Perspex.Controls.Platform public void Show() => _tl.Show(); public void BeginMoveDrag() => _tl.BeginMoveDrag(); + public void BeginResizeDrag(WindowEdge edge) => _tl.BeginResizeDrag(edge); public IDisposable ShowDialog() => _window.ShowDialog(); diff --git a/src/Perspex.Controls/TopLevel.cs b/src/Perspex.Controls/TopLevel.cs index dffedefbe2..12311df1c9 100644 --- a/src/Perspex.Controls/TopLevel.cs +++ b/src/Perspex.Controls/TopLevel.cs @@ -369,5 +369,11 @@ namespace Perspex.Controls /// Starts moving a window with left button being held. Should be called from left mouse button press event handler /// public void BeginMoveDrag() => PlatformImpl.BeginMoveDrag(); + + /// + /// Starts resizing a window. This function is used if an application has window resizing controls. + /// Should be called from left mouse button press event handler + /// + public void BeginResizeDrag(WindowEdge edge) => PlatformImpl.BeginResizeDrag(edge); } } diff --git a/src/Perspex.Controls/WindowEdge.cs b/src/Perspex.Controls/WindowEdge.cs new file mode 100644 index 0000000000..356f882899 --- /dev/null +++ b/src/Perspex.Controls/WindowEdge.cs @@ -0,0 +1,17 @@ +namespace Perspex.Controls +{ + + public enum WindowEdge + { + //Please don't reorder stuff here, I was lazy to write proper conversion code + //so the order of values is matching one from GTK + NorthWest = 0, + North, + NorthEast, + West, + East, + SouthWest, + South, + SouthEast, + } +} \ No newline at end of file diff --git a/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs index b19d771512..02aefb4106 100644 --- a/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs @@ -217,6 +217,34 @@ namespace Perspex.Win32.Interop WA_CLICKACTIVE, } + public enum HitTestValues + { + HTERROR = -2, + HTTRANSPARENT = -1, + HTNOWHERE = 0, + HTCLIENT = 1, + HTCAPTION = 2, + HTSYSMENU = 3, + HTGROWBOX = 4, + HTMENU = 5, + HTHSCROLL = 6, + HTVSCROLL = 7, + HTMINBUTTON = 8, + HTMAXBUTTON = 9, + HTLEFT = 10, + HTRIGHT = 11, + HTTOP = 12, + HTTOPLEFT = 13, + HTTOPRIGHT = 14, + HTBOTTOM = 15, + HTBOTTOMLEFT = 16, + HTBOTTOMRIGHT = 17, + HTBORDER = 18, + HTOBJECT = 19, + HTCLOSE = 20, + HTHELP = 21 + } + [Flags] public enum WindowStyles : uint { diff --git a/src/Windows/Perspex.Win32/WindowImpl.cs b/src/Windows/Perspex.Win32/WindowImpl.cs index 063be91873..ca1a2ae9c6 100644 --- a/src/Windows/Perspex.Win32/WindowImpl.cs +++ b/src/Windows/Perspex.Win32/WindowImpl.cs @@ -226,7 +226,25 @@ namespace Perspex.Win32 public void BeginMoveDrag() { UnmanagedMethods.DefWindowProc(_hwnd, (int) UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, - new IntPtr(2), IntPtr.Zero); + new IntPtr((int)UnmanagedMethods.HitTestValues.HTCAPTION), IntPtr.Zero); + } + + static readonly Dictionary EdgeDic = new Dictionary + { + {WindowEdge.East, UnmanagedMethods.HitTestValues.HTRIGHT}, + {WindowEdge.North, UnmanagedMethods.HitTestValues.HTTOP }, + {WindowEdge.NorthEast, UnmanagedMethods.HitTestValues.HTTOPRIGHT }, + {WindowEdge.NorthWest, UnmanagedMethods.HitTestValues.HTTOPLEFT }, + {WindowEdge.South, UnmanagedMethods.HitTestValues.HTBOTTOM }, + {WindowEdge.SouthEast, UnmanagedMethods.HitTestValues.HTBOTTOMRIGHT }, + {WindowEdge.SouthWest, UnmanagedMethods.HitTestValues.HTBOTTOMLEFT }, + {WindowEdge.West, UnmanagedMethods.HitTestValues.HTLEFT} + }; + + public void BeginResizeDrag(WindowEdge edge) + { + UnmanagedMethods.DefWindowProc(_hwnd, (int) UnmanagedMethods.WindowsMessage.WM_NCLBUTTONDOWN, + new IntPtr((int) EdgeDic[edge]), IntPtr.Zero); } public virtual IDisposable ShowDialog() diff --git a/src/iOS/Perspex.iOS/PerspexView.cs b/src/iOS/Perspex.iOS/PerspexView.cs index 1ccf78330f..92b2fac730 100644 --- a/src/iOS/Perspex.iOS/PerspexView.cs +++ b/src/iOS/Perspex.iOS/PerspexView.cs @@ -16,6 +16,7 @@ using Perspex.Skia.iOS; using UIKit; using Perspex.iOS.Specific; using ObjCRuntime; +using Perspex.Controls; namespace Perspex.iOS { @@ -112,6 +113,11 @@ namespace Perspex.iOS //Not supported } + public void BeginResizeDrag(WindowEdge edge) + { + //Not supported + } + public Size MaxClientSize => Bounds.Size.ToPerspex(); public void SetTitle(string title) {