using System; using System.Collections.Generic; using Chernobyl.Collections.Generic.Event; using Chernobyl.Event; using Chernobyl.Mathematics.Mechanics; namespace Chernobyl.Input.Controls.Axis { /// /// A helper class that allows for easy creation of IAxis classes. /// public abstract class AxisControl : Control, IAxisControl { /// /// Constructor. /// /// The services class that contains the /// dependencies that are to be injected into this object. protected AxisControl(IEventCollection services) : this(services, new List()) { } /// /// Constructor. /// /// The services class that contains the /// dependencies that are to be injected into this object. /// The list to use to hold the children controls. protected AxisControl(IEventCollection services, ICollection childList) : base(childList) { Sensitivity = 1.0f; } /// /// The amount the axis was in a certain direction /// (the previous value of "CurrentValue"). /// public float PreviousValue { get; protected set; } /// /// The amount the axis is in a certain direction currently. /// public float CurrentValue { get; private set; } /// /// The amount of change, from the axis' to /// its . /// public float ChangeAmount { get; private set; } /// /// Invoked when this axis moves. /// public event EventHandler> OnMove; /// /// Invoked when this axis moves up. /// public event EventHandler> OnUp; /// /// Invoked when this axis moves down. /// public event EventHandler> OnDown; /// /// Calculates the new and /// and raises events if necessary. /// /// The amount of time that has /// passed since this update was last called. public override void Update(TimeSpan deltaTime) { // The PreviousValue must be set prior to retrieving the value from // OverridableChangeAmount here because a derived class may use // PreviousValue to calculate the OverridableChangeAmount (mouse // axes may do this for example). PreviousValue = CurrentValue; ChangeAmount = OverridableChangeAmount * Sensitivity; CurrentValue = PreviousValue + ChangeAmount; // check if the new button state has changed if (ChangeAmount != 0.0f) { // yes it has EventArgs e = new EventArgs(this); if (ChangeAmount < 0.0f) { InvokeOnDown(this, e); InvokeOnMove(this, e); } else { InvokeOnUp(this, e); InvokeOnMove(this, e); } } base.Update(deltaTime); } /// /// The sensitivity of this axis. A sensitivity of 1 is the default. /// A lower sensitivity (between 0.0 and 1.0) causes this axis to report /// a smaller number for it's current value while a greater sensitivity /// (greater than 1.0) causes the value reported to be greater. /// public float Sensitivity { get; set; } /// /// The amount of change, from the axis' /// to its . Implementors should return /// the raw change amount and not try to apply /// to the returned value. The /// class will apply the /// value for you. /// protected abstract float OverridableChangeAmount { get; } /// /// Invokes the OnMove event. This method allows /// derived classes to invoke the event which is /// not directly allowed. /// /// The invoker of the event. /// The events arguments. protected void InvokeOnMove(IAxisControl sender, EventArgs e) { if (OnMove != null) OnMove(sender, e); } /// /// Invokes the OnDown event. This method allows /// derived classes to invoke the event which is /// not directly allowed. /// /// The invoker of the event. /// The events arguments. protected void InvokeOnDown(IAxisControl sender, EventArgs e) { if (OnDown != null) OnDown(sender, e); } /// /// Invokes the OnUp event. This method allows /// derived classes to invoke the event which is /// not directly allowed. /// /// The invoker of the event. /// The events arguments. protected void InvokeOnUp(IAxisControl sender, EventArgs e) { if (OnUp != null) OnUp(sender, e); } /// /// Holds all the action handler delegates that should /// be called when the the axis is moved. /// Action MoveActionHandlers { get; set; } /// /// Holds all the action handler delegates that should /// be called when the the axis is pressed moved down. /// Action DownActionHandlers { get; set; } /// /// Holds all the action handler delegates that should /// be called when the the axis is moved up. /// Action UpActionHandlers { get; set; } } }