using System; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Platform; namespace Avalonia { internal class ManagedWindowResizeDragHelper { private readonly IWindowBaseImpl _window; private readonly Action _captureMouse; private readonly Action _resize; private WindowEdge? _edge; private Point _prevPoint; public ManagedWindowResizeDragHelper(IWindowBaseImpl window, Action captureMouse, Action resize = null) { _window = window; _captureMouse = captureMouse; _resize = resize; } public void BeginResizeDrag(WindowEdge edge, Point currentMousePosition) { _captureMouse(true); _prevPoint = currentMousePosition; _edge = edge; } public bool PreprocessInputEvent(ref RawInputEventArgs e) { if (_edge == null) return false; if (e is RawMouseEventArgs args) { if (args.Type == RawMouseEventType.LeftButtonUp) { _edge = null; _captureMouse(false); } if (args.Type == RawMouseEventType.Move) { MoveWindow(args.Position); return true; } _edge = null; } return false; } private void MoveWindow(Point position) { var diff = position - _prevPoint; var edge = _edge.Value; var rc = new Rect(_window.Position, _window.ClientSize); if (edge == WindowEdge.East || edge == WindowEdge.NorthEast || edge == WindowEdge.SouthEast) { rc = rc.WithWidth(rc.Width + diff.X); _prevPoint = _prevPoint.WithX(position.X); } if (edge == WindowEdge.West || edge == WindowEdge.NorthWest || edge == WindowEdge.SouthWest) rc = rc.WithX(rc.X + diff.X).WithWidth(rc.Width - diff.X); if (edge == WindowEdge.South || edge == WindowEdge.SouthWest || edge == WindowEdge.SouthEast) { rc = rc.WithHeight(rc.Height + diff.Y); _prevPoint = _prevPoint.WithY(position.Y); } if (edge == WindowEdge.North || edge == WindowEdge.NorthWest || edge == WindowEdge.NorthEast) rc = rc.WithY(rc.Y + diff.Y).WithHeight(rc.Height - diff.Y); if (_resize != null) _resize(rc); else { if (_window.Position != rc.Position) _window.Position = rc.Position; if (_window.ClientSize != rc.Size) _window.Resize(rc.Size); } } } }