JD2022-TU1/main/tools/framework/JD.Sequencers/Times/TrackViewRubberBandingTool.cs

187 lines
5.2 KiB
C#

using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using JD.Sequencers.Controls;
using JD.Sequencers.Tools;
using JD.Sequencers.Windowlesses;
namespace JD.Sequencers.Times
{
public class TrackViewRubberBandingTool : SelectingTool
{
#region Variables
private readonly SelectionBox m_selectionBox = new SelectionBox();
private bool m_active;
private Point m_startPoint;
#endregion
#region Constructor
public TrackViewRubberBandingTool(TrackView trackView)
: base(trackView)
{
Container.Controls.Add(m_selectionBox);
}
#endregion
#region Properties
public new TrackView Container
{
get { return (TrackView)base.Container; }
}
public Timeline Timeline
{
get { return Container.Timeline; }
}
public SelectionBox SelectionBox
{
get { return m_selectionBox; }
}
private bool Active
{
get { return m_active; }
set
{
if (m_active != value)
{
m_active = value;
if (!m_active)
{
m_selectionBox.Reset();
}
else
{
m_selectionBox.Bounds = new Rectangle(Container.LastMouseDownEventArgs.Location, Size.Empty);
if (!IsShiftPressed && !IsControlPressed && Selection.Count > 0)
{
Selection.Clear();
}
}
}
}
}
#endregion
#region Overrides
protected internal override bool CanStart(ToolStartingEventArgs e)
{
if (e.Button != MouseButtons.Left || 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;
}
return base.CanStart(e);
}
protected internal override void OnMouseDown(MouseEventArgs e)
{
if (CanStart(new ToolStartingEventArgs(e)))
{
Active = true;
}
}
protected internal override void OnMouseMove(MouseEventArgs e)
{
if (!Active)
{
Active = true;
}
else
{
ComputeRubberBandBox(e.Location);
}
}
protected internal override void OnMouseUp(MouseEventArgs e)
{
if (Active)
{
ComputeRubberBandBox(e.Location);
DoRubberBand(e.Button, e.Location);
}
EndTool();
}
protected internal override void Start()
{
m_startPoint = Container.LastMouseDownEventArgs.Location;
}
protected internal override void End()
{
Active = false;
}
private void ComputeRubberBandBox(Point currentLocation)
{
Point p1 = m_startPoint;
Point p2 = currentLocation;
m_selectionBox.Bounds = new Rectangle(System.Math.Min(p2.X, p1.X), System.Math.Min(p2.Y, p1.Y), System.Math.Abs(p2.X - p1.X), System.Math.Abs(p2.Y - p1.Y));
}
private void DoRubberBand(MouseButtons button, Point location)
{
Size size = SystemInformation.DragSize;
if (m_selectionBox.Width <= (size.Width / 2) && m_selectionBox.Height <= (size.Height / 2))
{
DoSingleSelection(button, location, SelectionType.MouseDown | SelectionType.MouseUp);
}
else
{
SelectInRectangle(m_selectionBox.Bounds);
}
}
private void SelectInRectangle(Rectangle rect)
{
Selection.BeginUpdate();
foreach (WindowlessControl control in RetrieveControlsInRectangle(rect))
{
Selection.Add(control);
}
Selection.EndUpdate();
}
protected virtual IEnumerable<WindowlessControl> RetrieveControlsInRectangle(Rectangle rect)
{
foreach (Track track in Container.GetTracks().Where(t => t.IsVisible))
{
foreach (TrackItem control in track.Children)
{
Rectangle localRect = rect;
localRect.Offset(-control.Bounds.Left, -control.Bounds.Top);
if (control.IsVisible && control.Selectable && control.CaptureInput && rect.IntersectsWith(control.Bounds) && control.HitTestFilter(localRect))
{
yield return control;
}
}
}
}
#endregion
}
}