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)
{