mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-24 13:38:34 +01:00
Compare commits
No commits in common. "dca013e551ba44df31e786eaabbb47c9eeeef9fb" and "07eb6ac36f38b9d9d24afb26898371b33c75e1d7" have entirely different histories.
dca013e551
...
07eb6ac36f
7 changed files with 48 additions and 304 deletions
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using MLEM.Input;
|
|
||||||
using MLEM.Textures;
|
using MLEM.Textures;
|
||||||
|
|
||||||
namespace MLEM.Ui.Elements {
|
namespace MLEM.Ui.Elements {
|
||||||
|
@ -114,60 +111,6 @@ namespace MLEM.Ui.Elements {
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a <see cref="Button"/> that acts as a way to input a custom value for a <see cref="Keybind"/>.
|
|
||||||
/// Note that only the first <see cref="Keybind.Combination"/> of the given keybind is displayed and edited, all others are ignored. The exception is that, if <paramref name="unbindKey"/> is set, unbinding the keybind clears all combinations.
|
|
||||||
/// Inputting custom keybinds using this element supports <see cref="ModifierKey"/>-based modifiers and any <see cref="GenericInput"/>-based keys.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="anchor">The button's anchor</param>
|
|
||||||
/// <param name="size">The button's size</param>
|
|
||||||
/// <param name="keybind">The keybind that this button should represent</param>
|
|
||||||
/// <param name="inputHandler">The input handler to query inputs with</param>
|
|
||||||
/// <param name="activePlaceholder">A placeholder text that is displayed while the keybind is being edited</param>
|
|
||||||
/// <param name="unbindKey">An optional generic input that allows the keybind value to be unbound, clearing all combinations</param>
|
|
||||||
/// <param name="unboundPlaceholder">A placeholder text that is displayed if the keybind is unbound</param>
|
|
||||||
/// <param name="inputName">An optional function to give each input a display name that is easier to read. If this is null, <see cref="GenericInput.ToString"/> is used.</param>
|
|
||||||
/// <returns>A keybind button with the given settings</returns>
|
|
||||||
public static Button KeybindButton(Anchor anchor, Vector2 size, Keybind keybind, InputHandler inputHandler, string activePlaceholder, GenericInput unbindKey = default, string unboundPlaceholder = "", Func<GenericInput, string> inputName = null) {
|
|
||||||
string GetCurrentName() {
|
|
||||||
var combination = keybind.GetCombinations().FirstOrDefault();
|
|
||||||
if (combination == null)
|
|
||||||
return unboundPlaceholder;
|
|
||||||
return string.Join(" + ", combination.Modifiers
|
|
||||||
.Append(combination.Key)
|
|
||||||
.Select(i => inputName?.Invoke(i) ?? i.ToString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var button = new Button(anchor, size, GetCurrentName());
|
|
||||||
var active = false;
|
|
||||||
var activeNext = false;
|
|
||||||
button.OnPressed = e => {
|
|
||||||
button.Text.Text = activePlaceholder;
|
|
||||||
activeNext = true;
|
|
||||||
};
|
|
||||||
button.OnUpdated = (e, time) => {
|
|
||||||
if (activeNext) {
|
|
||||||
active = true;
|
|
||||||
activeNext = false;
|
|
||||||
} else if (active) {
|
|
||||||
if (unbindKey != default && inputHandler.IsPressed(unbindKey)) {
|
|
||||||
keybind.Clear();
|
|
||||||
button.Text.Text = unboundPlaceholder;
|
|
||||||
active = false;
|
|
||||||
} else if (inputHandler.InputsPressed.Length > 0) {
|
|
||||||
var key = inputHandler.InputsPressed.FirstOrDefault(i => !i.IsModifier());
|
|
||||||
if (key != default) {
|
|
||||||
var mods = inputHandler.InputsDown.Where(i => i.IsModifier());
|
|
||||||
keybind.Remove((c, i) => i == 0).Add(key, mods.ToArray());
|
|
||||||
button.Text.Text = GetCurrentName();
|
|
||||||
active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return button;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -57,11 +57,11 @@ namespace MLEM.Ui {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// AA <see cref="Keybind"/> that acts as the buttons on a gamepad that perform the <see cref="Element.OnPressed"/> action.
|
/// AA <see cref="Keybind"/> that acts as the buttons on a gamepad that perform the <see cref="Element.OnPressed"/> action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Keybind GamepadButtons = new Keybind(Buttons.A);
|
public readonly Keybind GamepadButtons = new Keybind().Add(Buttons.A);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A <see cref="Keybind"/> that acts as the buttons on a gamepad that perform the <see cref="Element.OnSecondaryPressed"/> action.
|
/// A <see cref="Keybind"/> that acts as the buttons on a gamepad that perform the <see cref="Element.OnSecondaryPressed"/> action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Keybind SecondaryGamepadButtons = new Keybind(Buttons.X);
|
public readonly Keybind SecondaryGamepadButtons = new Keybind().Add(Buttons.X);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A <see cref="Keybind"/> that acts as the buttons that select a <see cref="Element"/> that is above the currently selected element.
|
/// A <see cref="Keybind"/> that acts as the buttons that select a <see cref="Element"/> that is above the currently selected element.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -25,53 +25,6 @@ namespace MLEM.Input {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override string ToString() {
|
|
||||||
var ret = this.Type.ToString();
|
|
||||||
switch (this.Type) {
|
|
||||||
case InputType.Mouse:
|
|
||||||
ret += ((MouseButton) this).ToString();
|
|
||||||
break;
|
|
||||||
case InputType.Keyboard:
|
|
||||||
ret += ((Keys) this).ToString();
|
|
||||||
break;
|
|
||||||
case InputType.Gamepad:
|
|
||||||
ret += ((Buttons) this).ToString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool Equals(object obj) {
|
|
||||||
return obj is GenericInput o && this.Type == o.Type && this.value == o.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override int GetHashCode() {
|
|
||||||
return ((int) this.Type * 397) ^ this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compares the two generic input instances for equality using <see cref="Equals"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="left">The left input</param>
|
|
||||||
/// <param name="right">The right input</param>
|
|
||||||
/// <returns>Whether the two generic inputs are equal</returns>
|
|
||||||
public static bool operator ==(GenericInput left, GenericInput right) {
|
|
||||||
return left.Equals(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compares the two generic input instances for inequality using <see cref="Equals"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="left">The left input</param>
|
|
||||||
/// <param name="right">The right input</param>
|
|
||||||
/// <returns>Whether the two generic inputs are not equal</returns>
|
|
||||||
public static bool operator !=(GenericInput left, GenericInput right) {
|
|
||||||
return !left.Equals(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a <see cref="Keys"/> to a generic input.
|
/// Converts a <see cref="Keys"/> to a generic input.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -104,11 +57,11 @@ namespace MLEM.Input {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input">The input to convert</param>
|
/// <param name="input">The input to convert</param>
|
||||||
/// <returns>The resulting keys</returns>
|
/// <returns>The resulting keys</returns>
|
||||||
/// <exception cref="ArgumentException">If the given generic input's <see cref="Type"/> is not <see cref="InputType.Keyboard"/> or <see cref="InputType.None"/></exception>
|
/// <exception cref="ArgumentException">If the given generic input's <see cref="Type"/> is not <see cref="InputType.Keyboard"/></exception>
|
||||||
public static implicit operator Keys(GenericInput input) {
|
public static implicit operator Keys(GenericInput input) {
|
||||||
if (input.Type == InputType.None)
|
if (input.Type != InputType.Keyboard)
|
||||||
return Keys.None;
|
throw new ArgumentException();
|
||||||
return input.Type == InputType.Keyboard ? (Keys) input.value : throw new ArgumentException();
|
return (Keys) input.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -118,7 +71,9 @@ namespace MLEM.Input {
|
||||||
/// <returns>The resulting button</returns>
|
/// <returns>The resulting button</returns>
|
||||||
/// <exception cref="ArgumentException">If the given generic input's <see cref="Type"/> is not <see cref="InputType.Mouse"/></exception>
|
/// <exception cref="ArgumentException">If the given generic input's <see cref="Type"/> is not <see cref="InputType.Mouse"/></exception>
|
||||||
public static implicit operator MouseButton(GenericInput input) {
|
public static implicit operator MouseButton(GenericInput input) {
|
||||||
return input.Type == InputType.Mouse ? (MouseButton) input.value : throw new ArgumentException();
|
if (input.Type != InputType.Mouse)
|
||||||
|
throw new ArgumentException();
|
||||||
|
return (MouseButton) input.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -128,7 +83,9 @@ namespace MLEM.Input {
|
||||||
/// <returns>The resulting buttons</returns>
|
/// <returns>The resulting buttons</returns>
|
||||||
/// <exception cref="ArgumentException">If the given generic input's <see cref="Type"/> is not <see cref="InputType.Gamepad"/></exception>
|
/// <exception cref="ArgumentException">If the given generic input's <see cref="Type"/> is not <see cref="InputType.Gamepad"/></exception>
|
||||||
public static implicit operator Buttons(GenericInput input) {
|
public static implicit operator Buttons(GenericInput input) {
|
||||||
return input.Type == InputType.Gamepad ? (Buttons) input.value : throw new ArgumentException();
|
if (input.Type != InputType.Gamepad)
|
||||||
|
throw new ArgumentException();
|
||||||
|
return (Buttons) input.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -137,11 +94,6 @@ namespace MLEM.Input {
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public enum InputType {
|
public enum InputType {
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A type representing no value
|
|
||||||
/// </summary>
|
|
||||||
[EnumMember]
|
|
||||||
None,
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A type representing <see cref="MouseButton"/>
|
/// A type representing <see cref="MouseButton"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -23,7 +23,11 @@ namespace MLEM.Input {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public KeyboardState KeyboardState { get; private set; }
|
public KeyboardState KeyboardState { get; private set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set this field to false to disable keyboard handling for this input handler.
|
/// Contains the keyboard keys that are currently being pressed
|
||||||
|
/// </summary>
|
||||||
|
public Keys[] PressedKeys { get; private set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Set this property to false to disable keyboard handling for this input handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HandleKeyboard;
|
public bool HandleKeyboard;
|
||||||
|
|
||||||
|
@ -52,7 +56,7 @@ namespace MLEM.Input {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int LastScrollWheel => this.LastMouseState.ScrollWheelValue;
|
public int LastScrollWheel => this.LastMouseState.ScrollWheelValue;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set this field to false to disable mouse handling for this input handler.
|
/// Set this property to false to disable mouse handling for this input handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HandleMouse;
|
public bool HandleMouse;
|
||||||
|
|
||||||
|
@ -60,11 +64,11 @@ namespace MLEM.Input {
|
||||||
private readonly GamePadState[] gamepads = new GamePadState[GamePad.MaximumGamePadCount];
|
private readonly GamePadState[] gamepads = new GamePadState[GamePad.MaximumGamePadCount];
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the amount of gamepads that are currently connected.
|
/// Contains the amount of gamepads that are currently connected.
|
||||||
/// This field is automatically updated in <see cref="Update()"/>
|
/// This property is automatically updated in <see cref="Update()"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ConnectedGamepads { get; private set; }
|
public int ConnectedGamepads { get; private set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set this field to false to disable keyboard handling for this input handler.
|
/// Set this property to false to disable keyboard handling for this input handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HandleGamepads;
|
public bool HandleGamepads;
|
||||||
|
|
||||||
|
@ -83,7 +87,7 @@ namespace MLEM.Input {
|
||||||
public readonly ReadOnlyCollection<GestureSample> Gestures;
|
public readonly ReadOnlyCollection<GestureSample> Gestures;
|
||||||
private readonly List<GestureSample> gestures = new List<GestureSample>();
|
private readonly List<GestureSample> gestures = new List<GestureSample>();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set this field to false to disable touch handling for this input handler.
|
/// Set this property to false to disable touch handling for this input handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HandleTouch;
|
public bool HandleTouch;
|
||||||
|
|
||||||
|
@ -99,7 +103,7 @@ namespace MLEM.Input {
|
||||||
public TimeSpan KeyRepeatRate = TimeSpan.FromSeconds(0.05);
|
public TimeSpan KeyRepeatRate = TimeSpan.FromSeconds(0.05);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set this field to false to disable keyboard repeat event handling.
|
/// Set this property to false to disable keyboard repeat event handling.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HandleKeyboardRepeats = true;
|
public bool HandleKeyboardRepeats = true;
|
||||||
private DateTime heldKeyStart;
|
private DateTime heldKeyStart;
|
||||||
|
@ -108,7 +112,7 @@ namespace MLEM.Input {
|
||||||
private Keys heldKey;
|
private Keys heldKey;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set this field to false to disable gamepad repeat event handling.
|
/// Set this property to false to disable gamepad repeat event handling.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool HandleGamepadRepeats = true;
|
public bool HandleGamepadRepeats = true;
|
||||||
private readonly DateTime[] heldGamepadButtonStarts = new DateTime[GamePad.MaximumGamePadCount];
|
private readonly DateTime[] heldGamepadButtonStarts = new DateTime[GamePad.MaximumGamePadCount];
|
||||||
|
@ -116,23 +120,6 @@ namespace MLEM.Input {
|
||||||
private readonly bool[] triggerGamepadButtonRepeat = new bool[GamePad.MaximumGamePadCount];
|
private readonly bool[] triggerGamepadButtonRepeat = new bool[GamePad.MaximumGamePadCount];
|
||||||
private readonly Buttons?[] heldGamepadButtons = new Buttons?[GamePad.MaximumGamePadCount];
|
private readonly Buttons?[] heldGamepadButtons = new Buttons?[GamePad.MaximumGamePadCount];
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An array of all <see cref="Keys"/>, <see cref="Buttons"/> and <see cref="MouseButton"/> values that are currently down.
|
|
||||||
/// Note that this value only gets set if <see cref="StoreAllActiveInputs"/> is true.
|
|
||||||
/// </summary>
|
|
||||||
public GenericInput[] InputsDown { get; private set; }
|
|
||||||
/// <summary>
|
|
||||||
/// An array of all <see cref="Keys"/>, <see cref="Buttons"/> and <see cref="MouseButton"/> that are currently considered pressed.
|
|
||||||
/// An input is considered pressed if it was up in the last update, and is up in the current one.
|
|
||||||
/// Note that this value only gets set if <see cref="StoreAllActiveInputs"/> is true.
|
|
||||||
/// </summary>
|
|
||||||
public GenericInput[] InputsPressed { get; private set; }
|
|
||||||
private readonly List<GenericInput> inputsDownAccum = new List<GenericInput>();
|
|
||||||
/// <summary>
|
|
||||||
/// Set this field to false to enable <see cref="InputsDown"/> and <see cref="InputsPressed"/> being calculated.
|
|
||||||
/// </summary>
|
|
||||||
public bool StoreAllActiveInputs;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new input handler with optional initial values.
|
/// Creates a new input handler with optional initial values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -141,13 +128,11 @@ namespace MLEM.Input {
|
||||||
/// <param name="handleMouse">If mouse input should be handled</param>
|
/// <param name="handleMouse">If mouse input should be handled</param>
|
||||||
/// <param name="handleGamepads">If gamepad input should be handled</param>
|
/// <param name="handleGamepads">If gamepad input should be handled</param>
|
||||||
/// <param name="handleTouch">If touch input should be handled</param>
|
/// <param name="handleTouch">If touch input should be handled</param>
|
||||||
/// <param name="storeAllActiveInputs">Whether all inputs that are currently down and pressed should be calculated each update</param>
|
public InputHandler(Game game, bool handleKeyboard = true, bool handleMouse = true, bool handleGamepads = true, bool handleTouch = true) : base(game) {
|
||||||
public InputHandler(Game game, bool handleKeyboard = true, bool handleMouse = true, bool handleGamepads = true, bool handleTouch = true, bool storeAllActiveInputs = true) : base(game) {
|
|
||||||
this.HandleKeyboard = handleKeyboard;
|
this.HandleKeyboard = handleKeyboard;
|
||||||
this.HandleMouse = handleMouse;
|
this.HandleMouse = handleMouse;
|
||||||
this.HandleGamepads = handleGamepads;
|
this.HandleGamepads = handleGamepads;
|
||||||
this.HandleTouch = handleTouch;
|
this.HandleTouch = handleTouch;
|
||||||
this.StoreAllActiveInputs = storeAllActiveInputs;
|
|
||||||
this.Gestures = this.gestures.AsReadOnly();
|
this.Gestures = this.gestures.AsReadOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,18 +145,14 @@ namespace MLEM.Input {
|
||||||
if (this.HandleKeyboard) {
|
if (this.HandleKeyboard) {
|
||||||
this.LastKeyboardState = this.KeyboardState;
|
this.LastKeyboardState = this.KeyboardState;
|
||||||
this.KeyboardState = active ? Keyboard.GetState() : default;
|
this.KeyboardState = active ? Keyboard.GetState() : default;
|
||||||
var pressedKeys = this.KeyboardState.GetPressedKeys();
|
this.PressedKeys = this.KeyboardState.GetPressedKeys();
|
||||||
if (this.StoreAllActiveInputs) {
|
|
||||||
foreach (var pressed in pressedKeys)
|
|
||||||
this.inputsDownAccum.Add(pressed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.HandleKeyboardRepeats) {
|
if (this.HandleKeyboardRepeats) {
|
||||||
this.triggerKeyRepeat = false;
|
this.triggerKeyRepeat = false;
|
||||||
if (this.heldKey == Keys.None) {
|
if (this.heldKey == Keys.None) {
|
||||||
// if we're not repeating a key, set the first key being held to the repeat key
|
// if we're not repeating a key, set the first key being held to the repeat key
|
||||||
// note that modifier keys don't count as that wouldn't really make sense
|
// note that modifier keys don't count as that wouldn't really make sense
|
||||||
var key = pressedKeys.FirstOrDefault(k => !k.IsModifier());
|
var key = this.PressedKeys.FirstOrDefault(k => !k.IsModifier());
|
||||||
if (key != Keys.None) {
|
if (key != Keys.None) {
|
||||||
this.heldKey = key;
|
this.heldKey = key;
|
||||||
this.heldKeyStart = DateTime.UtcNow;
|
this.heldKeyStart = DateTime.UtcNow;
|
||||||
|
@ -203,12 +184,6 @@ namespace MLEM.Input {
|
||||||
var state = Mouse.GetState();
|
var state = Mouse.GetState();
|
||||||
if (active && this.Game.GraphicsDevice.Viewport.Bounds.Contains(state.Position)) {
|
if (active && this.Game.GraphicsDevice.Viewport.Bounds.Contains(state.Position)) {
|
||||||
this.MouseState = state;
|
this.MouseState = state;
|
||||||
if (this.StoreAllActiveInputs) {
|
|
||||||
foreach (var button in MouseExtensions.MouseButtons) {
|
|
||||||
if (state.GetState(button) == ButtonState.Pressed)
|
|
||||||
this.inputsDownAccum.Add(button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// mouse position and scroll wheel value should be preserved when the mouse is out of bounds
|
// mouse position and scroll wheel value should be preserved when the mouse is out of bounds
|
||||||
this.MouseState = new MouseState(state.X, state.Y, state.ScrollWheelValue, 0, 0, 0, 0, 0, state.HorizontalScrollWheelValue);
|
this.MouseState = new MouseState(state.X, state.Y, state.ScrollWheelValue, 0, 0, 0, 0, 0, state.HorizontalScrollWheelValue);
|
||||||
|
@ -219,23 +194,10 @@ namespace MLEM.Input {
|
||||||
this.ConnectedGamepads = GamePad.MaximumGamePadCount;
|
this.ConnectedGamepads = GamePad.MaximumGamePadCount;
|
||||||
for (var i = 0; i < GamePad.MaximumGamePadCount; i++) {
|
for (var i = 0; i < GamePad.MaximumGamePadCount; i++) {
|
||||||
this.lastGamepads[i] = this.gamepads[i];
|
this.lastGamepads[i] = this.gamepads[i];
|
||||||
var state = GamePadState.Default;
|
this.gamepads[i] = active ? GamePad.GetState(i) : default;
|
||||||
if (GamePad.GetCapabilities(i).IsConnected) {
|
if (this.ConnectedGamepads > i && !GamePad.GetCapabilities(i).IsConnected)
|
||||||
if (active) {
|
|
||||||
state = GamePad.GetState(i);
|
|
||||||
if (this.StoreAllActiveInputs) {
|
|
||||||
foreach (var button in EnumHelper.Buttons) {
|
|
||||||
if (state.IsButtonDown(button))
|
|
||||||
this.inputsDownAccum.Add(button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.ConnectedGamepads > i)
|
|
||||||
this.ConnectedGamepads = i;
|
this.ConnectedGamepads = i;
|
||||||
}
|
}
|
||||||
this.gamepads[i] = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.HandleGamepadRepeats) {
|
if (this.HandleGamepadRepeats) {
|
||||||
for (var i = 0; i < this.ConnectedGamepads; i++) {
|
for (var i = 0; i < this.ConnectedGamepads; i++) {
|
||||||
|
@ -276,17 +238,6 @@ namespace MLEM.Input {
|
||||||
while (active && TouchPanel.IsGestureAvailable)
|
while (active && TouchPanel.IsGestureAvailable)
|
||||||
this.gestures.Add(TouchPanel.ReadGesture());
|
this.gestures.Add(TouchPanel.ReadGesture());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.StoreAllActiveInputs) {
|
|
||||||
if (this.inputsDownAccum.Count <= 0) {
|
|
||||||
this.InputsPressed = Array.Empty<GenericInput>();
|
|
||||||
this.InputsDown = Array.Empty<GenericInput>();
|
|
||||||
} else {
|
|
||||||
this.InputsPressed = this.inputsDownAccum.Where(i => !this.InputsDown.Contains(i)).ToArray();
|
|
||||||
this.InputsDown = this.inputsDownAccum.ToArray();
|
|
||||||
this.inputsDownAccum.Clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="Update()"/>
|
/// <inheritdoc cref="Update()"/>
|
||||||
|
@ -523,7 +474,7 @@ namespace MLEM.Input {
|
||||||
case GenericInput.InputType.Mouse:
|
case GenericInput.InputType.Mouse:
|
||||||
return this.IsMouseButtonDown(control);
|
return this.IsMouseButtonDown(control);
|
||||||
default:
|
default:
|
||||||
return false;
|
throw new ArgumentException(nameof(control));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +495,7 @@ namespace MLEM.Input {
|
||||||
case GenericInput.InputType.Mouse:
|
case GenericInput.InputType.Mouse:
|
||||||
return this.IsMouseButtonUp(control);
|
return this.IsMouseButtonUp(control);
|
||||||
default:
|
default:
|
||||||
return true;
|
throw new ArgumentException(nameof(control));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +516,7 @@ namespace MLEM.Input {
|
||||||
case GenericInput.InputType.Mouse:
|
case GenericInput.InputType.Mouse:
|
||||||
return this.IsMouseButtonPressed(control);
|
return this.IsMouseButtonPressed(control);
|
||||||
default:
|
default:
|
||||||
return false;
|
throw new ArgumentException(nameof(control));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
@ -13,27 +12,7 @@ namespace MLEM.Input {
|
||||||
public class Keybind {
|
public class Keybind {
|
||||||
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
private Combination[] combinations = Array.Empty<Combination>();
|
private readonly List<Combination> combinations = new List<Combination>();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new keybind and adds the given key and modifiers using <see cref="Add(MLEM.Input.GenericInput,MLEM.Input.GenericInput[])"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The key to be pressed.</param>
|
|
||||||
/// <param name="modifiers">The modifier keys that have to be held down.</param>
|
|
||||||
public Keybind(GenericInput key, params GenericInput[] modifiers) {
|
|
||||||
this.Add(key, modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="Keybind(GenericInput, GenericInput[])"/>
|
|
||||||
public Keybind(GenericInput key, ModifierKey modifier) {
|
|
||||||
this.Add(key, modifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new keybind with no default combinations
|
|
||||||
/// </summary>
|
|
||||||
public Keybind() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a new key combination to this keybind that can optionally be pressed for the keybind to trigger.
|
/// Adds a new key combination to this keybind that can optionally be pressed for the keybind to trigger.
|
||||||
|
@ -42,7 +21,7 @@ namespace MLEM.Input {
|
||||||
/// <param name="modifiers">The modifier keys that have to be held down.</param>
|
/// <param name="modifiers">The modifier keys that have to be held down.</param>
|
||||||
/// <returns>This keybind, for chaining</returns>
|
/// <returns>This keybind, for chaining</returns>
|
||||||
public Keybind Add(GenericInput key, params GenericInput[] modifiers) {
|
public Keybind Add(GenericInput key, params GenericInput[] modifiers) {
|
||||||
this.combinations = this.combinations.Append(new Combination(key, modifiers)).ToArray();
|
this.combinations.Add(new Combination(key, modifiers));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,17 +35,7 @@ namespace MLEM.Input {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>This keybind, for chaining</returns>
|
/// <returns>This keybind, for chaining</returns>
|
||||||
public Keybind Clear() {
|
public Keybind Clear() {
|
||||||
this.combinations = Array.Empty<Combination>();
|
this.combinations.Clear();
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes all combinations that match the given predicate
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="predicate">The predicate to match against</param>
|
|
||||||
/// <returns>This keybind, for chaining</returns>
|
|
||||||
public Keybind Remove(Func<Combination, int, bool> predicate) {
|
|
||||||
this.combinations = this.combinations.Where((c, i) => !predicate(c, i)).ToArray();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +46,7 @@ namespace MLEM.Input {
|
||||||
/// <param name="other">The keybind to copy from</param>
|
/// <param name="other">The keybind to copy from</param>
|
||||||
/// <returns>This keybind, for chaining</returns>
|
/// <returns>This keybind, for chaining</returns>
|
||||||
public Keybind CopyFrom(Keybind other) {
|
public Keybind CopyFrom(Keybind other) {
|
||||||
this.combinations = this.combinations.Concat(other.combinations).ToArray();
|
this.combinations.AddRange(other.combinations);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,85 +72,29 @@ namespace MLEM.Input {
|
||||||
return this.combinations.Any(c => c.IsPressed(handler, gamepadIndex));
|
return this.combinations.Any(c => c.IsPressed(handler, gamepadIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns whether any of this keybind's modifier keys are currently down.
|
|
||||||
/// See <see cref="InputHandler.IsDown"/> for more information.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="handler">The input handler to query the keys with</param>
|
|
||||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
|
||||||
/// <returns>Whether any of this keyboard's modifier keys are down</returns>
|
|
||||||
public bool IsModifierDown(InputHandler handler, int gamepadIndex = -1) {
|
|
||||||
return this.combinations.Any(c => c.IsModifierDown(handler, gamepadIndex));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns an enumerable of all of the combinations that this keybind currently contains
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>This keybind's combinations</returns>
|
|
||||||
public IEnumerable<Combination> GetCombinations() {
|
|
||||||
foreach (var combination in this.combinations)
|
|
||||||
yield return combination;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A key combination is a combination of a set of modifier keys and a key.
|
|
||||||
/// All of the keys are <see cref="GenericInput"/> instances, so they can be keyboard-, mouse- or gamepad-based.
|
|
||||||
/// </summary>
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public class Combination {
|
private class Combination {
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The inputs that have to be held down for this combination to be valid.
|
|
||||||
/// If this collection is empty, there are no required modifier keys.
|
|
||||||
/// </summary>
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public readonly GenericInput[] Modifiers;
|
private readonly GenericInput[] modifiers;
|
||||||
/// <summary>
|
|
||||||
/// The input that has to be down (or pressed) for this combination to be considered down (or pressed).
|
|
||||||
/// Note that <see cref="Modifiers"/> needs to be empty, or all of its values need to be down, as well.
|
|
||||||
/// </summary>
|
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public readonly GenericInput Key;
|
private readonly GenericInput key;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new combination with the given settings.
|
|
||||||
/// To add a combination to a <see cref="Keybind"/>, use <see cref="Keybind.Add(MLEM.Input.GenericInput,MLEM.Input.GenericInput[])"/> instead.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="key">The key</param>
|
|
||||||
/// <param name="modifiers">The modifiers</param>
|
|
||||||
public Combination(GenericInput key, GenericInput[] modifiers) {
|
public Combination(GenericInput key, GenericInput[] modifiers) {
|
||||||
this.Modifiers = modifiers;
|
this.modifiers = modifiers;
|
||||||
this.Key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
internal bool IsDown(InputHandler handler, int gamepadIndex = -1) {
|
||||||
/// Returns whether this combination is currently down
|
return this.IsModifierDown(handler, gamepadIndex) && handler.IsDown(this.key, gamepadIndex);
|
||||||
/// </summary>
|
|
||||||
/// <param name="handler">The input handler to query the keys with</param>
|
|
||||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
|
||||||
/// <returns>Whether this combination is down</returns>
|
|
||||||
public bool IsDown(InputHandler handler, int gamepadIndex = -1) {
|
|
||||||
return this.IsModifierDown(handler, gamepadIndex) && handler.IsDown(this.Key, gamepadIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
internal bool IsPressed(InputHandler handler, int gamepadIndex = -1) {
|
||||||
/// Returns whether this combination is currently pressed
|
return this.IsModifierDown(handler, gamepadIndex) && handler.IsPressed(this.key, gamepadIndex);
|
||||||
/// </summary>
|
|
||||||
/// <param name="handler">The input handler to query the keys with</param>
|
|
||||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
|
||||||
/// <returns>Whether this combination is pressed</returns>
|
|
||||||
public bool IsPressed(InputHandler handler, int gamepadIndex = -1) {
|
|
||||||
return this.IsModifierDown(handler, gamepadIndex) && handler.IsPressed(this.Key, gamepadIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private bool IsModifierDown(InputHandler handler, int gamepadIndex = -1) {
|
||||||
/// Returns whether this combination's modifier keys are currently down
|
return this.modifiers.Length <= 0 || this.modifiers.Any(m => handler.IsDown(m, gamepadIndex));
|
||||||
/// </summary>
|
|
||||||
/// <param name="handler">The input handler to query the keys with</param>
|
|
||||||
/// <param name="gamepadIndex">The index of the gamepad to query, or -1 to query all gamepads</param>
|
|
||||||
/// <returns>Whether this combination's modifiers are down</returns>
|
|
||||||
public bool IsModifierDown(InputHandler handler, int gamepadIndex = -1) {
|
|
||||||
return this.Modifiers.Length <= 0 || this.Modifiers.Any(m => handler.IsDown(m, gamepadIndex));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,11 +50,6 @@ namespace MLEM.Input {
|
||||||
return ModifierKey.None;
|
return ModifierKey.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="GetModifier(Microsoft.Xna.Framework.Input.Keys)"/>
|
|
||||||
public static ModifierKey GetModifier(this GenericInput input) {
|
|
||||||
return input.Type == GenericInput.InputType.Keyboard ? GetModifier((Keys) input) : ModifierKey.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns whether the given key is a modifier key or not.
|
/// Returns whether the given key is a modifier key or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -64,11 +59,6 @@ namespace MLEM.Input {
|
||||||
return GetModifier(key) != ModifierKey.None;
|
return GetModifier(key) != ModifierKey.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IsModifier(Microsoft.Xna.Framework.Input.Keys)"/>
|
|
||||||
public static bool IsModifier(this GenericInput input) {
|
|
||||||
return GetModifier(input) != ModifierKey.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -78,7 +68,7 @@ namespace MLEM.Input {
|
||||||
public enum ModifierKey {
|
public enum ModifierKey {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// No modifier key. Only used for <see cref="KeysExtensions.GetModifier(Keys)"/>
|
/// No modifier key. Only used for <see cref="KeysExtensions.GetModifier"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
None,
|
None,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -230,11 +230,6 @@ namespace Sandbox {
|
||||||
if (delta != 0) {
|
if (delta != 0) {
|
||||||
this.camera.Zoom(0.1F * Math.Sign(delta), this.InputHandler.MousePosition.ToVector2());
|
this.camera.Zoom(0.1F * Math.Sign(delta), this.InputHandler.MousePosition.ToVector2());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.InputsDown.Length > 0)
|
|
||||||
Console.WriteLine("Down: " + string.Join(", ", Input.InputsDown));
|
|
||||||
if (Input.InputsPressed.Length > 0)
|
|
||||||
Console.WriteLine("Pressed: " + string.Join(", ", Input.InputsPressed));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void DoDraw(GameTime gameTime) {
|
protected override void DoDraw(GameTime gameTime) {
|
||||||
|
|
Loading…
Reference in a new issue