160 lines
4.7 KiB
C#
160 lines
4.7 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Windows.Forms;
|
|
using JD.Sequencers.Controls;
|
|
using JD.Sequencers.Windowlesses;
|
|
|
|
namespace JD.Sequencers.Tools
|
|
{
|
|
/// <summary>
|
|
/// Basic tool that moves controls.
|
|
/// </summary>
|
|
public class DraggingTool : Tool
|
|
{
|
|
#region Variables
|
|
|
|
private Point m_lastMovePosition;
|
|
private Point m_lastOriginalMovePosition;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
/// <summary>
|
|
/// Constructor.
|
|
/// </summary>
|
|
/// <param name="owner"></param>
|
|
public DraggingTool(WindowlessContainer owner)
|
|
: base(owner)
|
|
{
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
protected Point InitialMovePosition { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
protected internal override bool CanStart(ToolStartingEventArgs e)
|
|
{
|
|
if (e.Button != MouseButtons.Left)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (Selection.Count == 0 || Selection.Any(x => !x.CanDrag))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (Container.LastMouseDownEventArgs == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Size size = SystemInformation.DragSize;
|
|
Point p1 = Container.LastMouseDownEventArgs.Location;
|
|
Point p2 = e.Location;
|
|
if ((System.Math.Abs(p1.X - p2.X) <= (size.Width / 2)) && (System.Math.Abs(p1.Y - p2.Y) <= (size.Height / 2)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
WindowlessControl control = Container.FindSelectableControl<WindowlessControl>(Container.LastMouseDownEventArgs.Location);
|
|
|
|
if (!Selection.Contains(control))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return base.CanStart(e);
|
|
}
|
|
|
|
protected internal override void Start()
|
|
{
|
|
base.Start();
|
|
|
|
InitialMovePosition = Container.LastMouseDownEventArgs.Location;
|
|
m_lastMovePosition = Container.LastMouseDownEventArgs.Location;
|
|
m_lastOriginalMovePosition = m_lastMovePosition;
|
|
|
|
// Find which control is the main "dragged one" in the current selection.
|
|
CurrentControl = Container.FindControl<WindowlessControl>(m_lastMovePosition, control => control.Selected) ?? Selection.FirstOrDefault();
|
|
|
|
foreach (WindowlessControl control in Selection)
|
|
{
|
|
control.OnBeginMoving();
|
|
}
|
|
|
|
Started?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
|
|
protected internal override void End()
|
|
{
|
|
base.End();
|
|
|
|
foreach (WindowlessControl control in Selection)
|
|
{
|
|
control.OnEndMoving();
|
|
}
|
|
Ended?.Invoke(this, EventArgs.Empty);
|
|
}
|
|
|
|
protected internal override void OnMouseMove(MouseEventArgs e)
|
|
{
|
|
base.OnMouseMove(e);
|
|
|
|
// Make sure selection contains something
|
|
if (Selection.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// This avoids moving objects without any user impulsion. This can occur otherwise since
|
|
// we always compute the cursor delta by considering the last "snap" that altered the cursor location.
|
|
if (e.Location == m_lastOriginalMovePosition)
|
|
{
|
|
return;
|
|
}
|
|
m_lastOriginalMovePosition = e.Location;
|
|
|
|
Point newPosition = e.Location;
|
|
MoveSelection(ref newPosition, m_lastMovePosition);
|
|
|
|
var selectionMoved = new SelectionMovedEventArgs { NewLocation = newPosition, OriginalLocation = m_lastMovePosition };
|
|
SelectionMoved?.Invoke(this, selectionMoved);
|
|
|
|
m_lastMovePosition = selectionMoved.NewLocation;
|
|
}
|
|
|
|
protected virtual void MoveSelection(ref Point newPosition, Point oldPosition)
|
|
{
|
|
Point delta = new Point(newPosition.X - oldPosition.X,
|
|
newPosition.Y - oldPosition.Y);
|
|
Point location;
|
|
foreach (WindowlessControl control in Selection)
|
|
{
|
|
location = control.Location;
|
|
location.Offset(delta);
|
|
control.Location = location;
|
|
}
|
|
}
|
|
|
|
private static bool CanResizeControl(WindowlessControl control)
|
|
{
|
|
return control is IMovable movable &&
|
|
movable.IsMoveAllowed;
|
|
}
|
|
|
|
public event EventHandler<SelectionMovedEventArgs> SelectionMoved;
|
|
public event EventHandler Started;
|
|
public event EventHandler Ended;
|
|
|
|
#endregion
|
|
}
|
|
}
|