using System; using System.ComponentModel; using JD.Kernel.StaticHelpers; using JD.Kernel.Structs; using JD.Sequencers.Times; using JD.Sequencers.Windowlesses; namespace JD.Sequencers.Controls { using RangeF = Range; /// /// Base class for objects that "live on the timeline". /// public class Guide : WindowlessControl, IMovable { #region Variables private readonly Timeline m_timeline; private float m_time; private RangeF m_range = RangeF.Infinite; private bool m_isMoveAllowed = true; private bool m_snap = true; #endregion #region Constructor public Guide(Timeline timeline) { Throw.IfNull(timeline, "timeline"); m_timeline = timeline; } #endregion #region Properties public Timeline Timeline { get { return m_timeline; } } /// /// Time at which the guide is. /// public float Time { get { return m_time; } set { if (m_time != value) { if (OnTimeChanging(new MarkerCancelEventArgs(value))) { m_time = Range.Clamp(value); OnTimeChanged(EventArgs.Empty); } } } } /// /// Valid range for the guide. /// public RangeF Range { get { return m_range; } set { m_range = value; } } public bool Snap { get { return m_snap; } set { m_snap = value; } } #endregion #region Events public event EventHandler TimeChanging; protected virtual bool OnTimeChanging(MarkerCancelEventArgs e) { TimeChanging?.Invoke(this, e); return !e.Cancel; } public event EventHandler TimeChanged; protected virtual void OnTimeChanged(EventArgs e) { TimeChanged?.Invoke(this, e); } #endregion #region IMovable Members public bool IsMoveAllowed { get { return m_isMoveAllowed; } set { m_isMoveAllowed = value; } } public void Snap_Self(float originalDelta, ref float snappedDelta, ref float diff) { if (m_snap) { Timeline.SnapDelta(originalDelta, Time, ref snappedDelta, ref diff); } } public virtual void Snap_Bounds(float originalDelta, ref float snappedDelta, ref float diff) { if (Time + snappedDelta < Range.Min) { snappedDelta = Range.Min - Time; } else if (Time + snappedDelta >= Range.Max) { snappedDelta = Range.Max - Time; } } public void Move(float delta) { Time += delta; Timeline.Invalidate(); } #endregion #region Inner Types public class MarkerCancelEventArgs : CancelEventArgs { #region Variables private readonly float m_newTime; #endregion #region Constructor public MarkerCancelEventArgs(float newTime) : this(newTime, false) { } public MarkerCancelEventArgs(float newTime, bool cancel) : base(cancel) { m_newTime = newTime; } #endregion #region Properties public float NewTime { get { return m_newTime; } } #endregion } #endregion } }