using System;
using System.Drawing;
using System.Windows.Forms;
namespace PKHeX.WinForms.Controls;
///
/// Manages drag-and-drop operations for slot controls.
///
public sealed class DragManager : IDisposable
{
///
/// Gets the current slot change information for drag-and-drop operations.
///
public SlotChangeInfo Info { get; private set; } = new();
///
/// Occurs when an external drag-and-drop operation is requested.
///
public event DragEventHandler? RequestExternalDragDrop;
private BitmapCursor? OwnedCursor;
///
/// Requests a drag-and-drop operation.
///
/// The sender of the event.
/// The drag event arguments.
public void RequestDD(object sender, DragEventArgs e) => RequestExternalDragDrop?.Invoke(sender, e);
///
/// Sets the cursor for the specified form and updates the drag info.
///
/// The form to set the cursor for.
/// The cursor to set.
public void SetCursor(Control f, Cursor? z)
{
if (OwnedCursor is not null && !ReferenceEquals(OwnedCursor.Cursor, z))
DisposeOwnedCursor();
f.Cursor = z;
Info.Cursor = z;
}
public void SetOwnedCursor(Control f, Bitmap bitmap)
{
DisposeOwnedCursor();
OwnedCursor = new BitmapCursor(bitmap);
SetCursor(f, OwnedCursor.Cursor);
}
///
/// Resets the cursor for the specified form to the default cursor.
///
/// The form to reset the cursor for.
public void ResetCursor(Control sender)
{
SetCursor(sender, Cursors.Default);
}
///
/// Initializes the drag manager and resets the drag info.
///
public void Initialize()
{
DisposeOwnedCursor();
Info = new SlotChangeInfo();
}
///
/// Resets the drag manager's slot change info.
///
public void Reset()
{
DisposeOwnedCursor();
Info.Reset();
}
private void DisposeOwnedCursor()
{
if (OwnedCursor is null)
return;
OwnedCursor.Dispose();
OwnedCursor = null;
}
public void Dispose() => DisposeOwnedCursor();
///
/// Gets or sets the mouse down position for drag detection.
///
public Point MouseDownPosition { private get; set; }
///
/// Gets a value indicating whether a drag operation can be started.
///
public bool CanStartDrag => Info.IsLeftMouseDown && ((Math.Abs(Cursor.Position.X - MouseDownPosition.X) + Math.Abs(Cursor.Position.Y - MouseDownPosition.Y)) > Main.Settings.Advanced.DragStartThreshold);
}