using SFML.Window;
using System.Collections.Generic;
namespace Otter {
///
/// Component used for interpreting input as a button. It can recieve input from multiple sources
/// including keyboard, mouse buttons, or joystick buttons and axes. The button input can also be
/// controlled in code.
///
public class Button : Component {
#region Private Fields
bool buttonsDown = false,
currentButtonsDown = false,
prevButtonsDown = false;
#endregion
#region Public Fields
///
/// The keys registered to the Button.
///
public List Keys = new List();
///
/// The joystick Buttons registered to the Button.
///
public List> JoyButtons = new List>();
///
/// The mouse buttons registered to the Button.
///
public List MouseButtons = new List();
///
/// The mouse wheel registered to the Button.
///
public List MouseWheel = new List();
///
/// Determines if the Button is enabled. If not enabled all tests return false.
///
public bool Enabled = true;
///
/// The time passed since the last button press.
///
public float LastPressed = float.MaxValue;
///
/// The time passed since the last button release.
///
public float LastReleased = float.MaxValue;
#endregion
#region Public Properties
///
/// If the button is currently controlled
///
public bool ForcedInput { get; private set; }
///
/// Check if the button has been pressed.
///
public bool Pressed {
get {
if (!Enabled) return false;
return currentButtonsDown && !prevButtonsDown;
}
}
///
/// Check if the button has been released.
///
public bool Released {
get {
if (!Enabled) return false;
return !currentButtonsDown && prevButtonsDown;
}
}
///
/// Check if the button is down.
///
public bool Down {
get {
if (!Enabled) return false;
return currentButtonsDown;
}
}
///
/// Check if the button is up.
///
public bool Up {
get {
if (!Enabled) return false;
return !currentButtonsDown;
}
}
///
/// Returns true if this button is using any JoyButtons from a Joystick.
///
public bool IsUsingJoyButtons {
get {
foreach (var joyId in JoyButtons) {
if (joyId.Count > 0) return true;
}
return false;
}
}
#endregion
#region Constructors
///
/// Create a Button.
///
/// Optional string name of the button.
public Button() {
for (var i = 0; i < Joystick.Count; i++) {
JoyButtons.Add(new List());
}
}
///
/// Create a Button by copying another existing Button.
///
/// The Button to copy.
public Button(Button source) : this() {
AddButton(source);
}
#endregion
#region Public Methods
///
/// Reset the Button to report no input.
///
public void Reset() {
buttonsDown = false;
prevButtonsDown = false;
currentButtonsDown = false;
}
///
/// Clear all registered inputs for the Button.
///
public void Clear() {
Keys.Clear();
JoyButtons.Clear();
MouseButtons.Clear();
MouseWheel.Clear();
}
///
/// Add a keyboard Key to the Button.
///
/// The key to add.
/// The Button.
public Button AddKey(params Key[] keys) {
foreach (var k in keys) {
Keys.Add(k);
}
return this;
}
///
/// Add a mouse button to the Button.
///
/// The mouse button to add.
/// The Button.
public Button AddMouseButton(params MouseButton[] mouseButtons) {
foreach (var mb in mouseButtons) {
MouseButtons.Add(mb);
}
return this;
}
///
/// Add the mouse wheel to the Button.
///
/// The mouse wheel direction to add.
/// The Button.
public Button AddMouseWheel(MouseWheelDirection direction) {
MouseWheel.Add(direction);
return this;
}
///
/// Add a joystick button to the Button.
///
/// The joystick button to add.
/// The joystick id of the button to add.
/// The Button.
public Button AddJoyButton(int button, int joystick = 0) {
JoyButtons[joystick].Add(button);
return this;
}
///
/// Add another Button into this Button.
///
/// The Button to add into this Button.
/// The Button.
public Button AddButton(Button source) {
Keys.AddRange(source.Keys);
JoyButtons.EachWithIndex((b, i) => {
JoyButtons[i].AddRange(source.JoyButtons[i]);
});
MouseButtons.AddRange(source.MouseButtons);
MouseWheel.AddRange(source.MouseWheel);
return this;
}
///
/// Add a joystick AxisButton to the Button.
///
/// The AxisButton to add.
/// The joystick id of the button to add.
/// The Button.
public Button AddAxisButton(AxisButton button, int joystick = 0) {
AddJoyButton((int)button, joystick);
return this;
}
///
/// Force the state of the button. This will override player input.
///
/// The state of the button, true for down, false for up.
public void ForceState(bool state) {
forceDown = state;
ForcedInput = true;
}
///
/// Release the button's state from forced control. Restores player input.
///
public void ReleaseState() {
ForcedInput = false;
}
///
/// Update the button status.
///
public override void UpdateFirst() {
base.UpdateFirst();
buttonsDown = false;
// Fix for buttons that arent being updated.
if (LastPressed == float.MaxValue) LastPressed = 0;
if (LastReleased == float.MaxValue) LastReleased = 0;
foreach (var k in Keys) {
if (Input.Instance.KeyDown(k)) {
buttonsDown = true;
}
}
for (int i = 0; i < JoyButtons.Count; i++) {
foreach (var button in JoyButtons[i]) {
if (Input.Instance.ButtonDown(button, i)) {
buttonsDown = true;
}
}
}
foreach (var mb in MouseButtons) {
if (Input.Instance.MouseButtonDown(mb)) {
buttonsDown = true;
}
}
foreach (var w in MouseWheel) {
if (w == MouseWheelDirection.Down) {
if (Input.Instance.MouseWheelDelta > 0) {
buttonsDown = true;
}
}
if (w == MouseWheelDirection.Up) {
if (Input.Instance.MouseWheelDelta < 0) {
buttonsDown = true;
}
}
}
if (ForcedInput) {
buttonsDown = false;
if (forceDown) buttonsDown = true;
}
prevButtonsDown = currentButtonsDown;
currentButtonsDown = buttonsDown;
LastPressed += Game.Instance.DeltaTime;
if (Pressed) {
LastPressed = 0;
}
LastReleased += Game.Instance.DeltaTime;
if (Released) {
LastReleased = 0;
}
}
#endregion
#region Internal
internal bool forceDown = false;
#endregion
}
}