JD2022-TU1/main/tools/framework/JD.Sequencers/Controls/Guide.cs

176 lines
3.9 KiB
C#

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<float>;
/// <summary>
/// Base class for objects that "live on the timeline".
/// </summary>
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; }
}
/// <summary>
/// Time at which the guide is.
/// </summary>
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);
}
}
}
}
/// <summary>
/// Valid range for the guide.
/// </summary>
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<MarkerCancelEventArgs> 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
}
}