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 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 } }