mirror of
https://github.com/AlexMacocian/MonoGame.Extended.git
synced 2026-07-24 12:06:37 +00:00
278 lines
9.5 KiB
C#
278 lines
9.5 KiB
C#
using Microsoft.Xna.Framework.Input;
|
|
using MonoGame.Extended.Input;
|
|
using MonoGame.Extended.Input.InputListeners;
|
|
|
|
namespace MonoGame.Extended.NuclexGui.Controls
|
|
{
|
|
/// <summary>
|
|
/// Determines where the text or image describing control will be located.
|
|
/// Used primarily for radio button and checkbox.
|
|
/// </summary>
|
|
public enum GuiPressableDescriptionPosition
|
|
{
|
|
North,
|
|
South,
|
|
West,
|
|
East
|
|
}
|
|
|
|
/// <summary>User interface element the user can push down</summary>
|
|
public abstract class GuiPressableControl : GuiControl, IFocusable
|
|
{
|
|
/// <summary>Whether the mouse is hovering over the command</summary>
|
|
private bool _mouseHovering;
|
|
|
|
/// <summary>Whether the command is pressed down using the game pad shortcut</summary>
|
|
private bool _pressedDownByGamepadShortcut;
|
|
|
|
/// <summary>Whether the command is pressed down using the space key</summary>
|
|
private bool _pressedDownByKeyboard;
|
|
|
|
/// <summary>Whether the command is pressed down using the keyboard shortcut</summary>
|
|
private bool _pressedDownByKeyboardShortcut;
|
|
|
|
/// <summary>Whether the command is pressed down using the mouse</summary>
|
|
private bool _pressedDownByMouse;
|
|
|
|
/// <summary>Whether the user can interact with the choice</summary>
|
|
public bool Enabled;
|
|
|
|
/// <summary>Button that can be pressed to activate this command</summary>
|
|
public Buttons? ShortcutButton;
|
|
|
|
/// <summary>Initializes a new command control</summary>
|
|
public GuiPressableControl()
|
|
{
|
|
Enabled = true;
|
|
}
|
|
|
|
/// <summary>Whether the mouse pointer is hovering over the control</summary>
|
|
public bool MouseHovering => _mouseHovering;
|
|
|
|
/// <summary>Whether the pressable control is in the depressed state</summary>
|
|
public virtual bool Depressed
|
|
{
|
|
get
|
|
{
|
|
var mousePressed = _mouseHovering && _pressedDownByMouse;
|
|
return
|
|
mousePressed ||
|
|
_pressedDownByKeyboard ||
|
|
_pressedDownByKeyboardShortcut ||
|
|
_pressedDownByGamepadShortcut;
|
|
}
|
|
}
|
|
|
|
/// <summary>Whether the control currently has the input focus</summary>
|
|
public bool HasFocus => (Screen != null) &&
|
|
ReferenceEquals(Screen.FocusedControl, this);
|
|
|
|
/// <summary>Whether the control can currently obtain the input focus</summary>
|
|
bool IFocusable.CanGetFocus => Enabled;
|
|
|
|
/// <summary>
|
|
/// Called when the mouse has entered the control and is now hovering over it
|
|
/// </summary>
|
|
protected override void OnMouseEntered()
|
|
{
|
|
_mouseHovering = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when the mouse has left the control and is no longer hovering over it
|
|
/// </summary>
|
|
protected override void OnMouseLeft(float x, float y)
|
|
{
|
|
// Intentionally not calling OnActivated() here because the user has moved
|
|
// the mouse away from the command while holding the mouse button down -
|
|
// a common trick under windows to last-second-abort the clicking of a button
|
|
_mouseHovering = false;
|
|
}
|
|
|
|
/// <summary>Called when a mouse button has been pressed down</summary>
|
|
/// <param name="button">Index of the button that has been pressed</param>
|
|
protected override void OnMousePressed(MouseButton button)
|
|
{
|
|
if (Enabled)
|
|
{
|
|
if (button == MouseButton.Left)
|
|
_pressedDownByMouse = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>Called when a mouse button has been released again</summary>
|
|
/// <param name="button">Index of the button that has been released</param>
|
|
protected override void OnMouseReleased(MouseButton button)
|
|
{
|
|
if (button == MouseButton.Left)
|
|
{
|
|
_pressedDownByMouse = false;
|
|
|
|
// Only trigger the pressed event if the mouse was released over the control.
|
|
// The user can move the mouse cursor away from the control while still holding
|
|
// the mouse button down to do the well-known last-second-abort.
|
|
if (_mouseHovering && Enabled)
|
|
{
|
|
if (!Depressed)
|
|
OnPressed();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Called when a button on the gamepad has been pressed</summary>
|
|
/// <param name="button">Button that has been pressed</param>
|
|
/// <returns>
|
|
/// True if the button press was handled by the control, otherwise false.
|
|
/// </returns>
|
|
protected override bool OnButtonPressed(Buttons button)
|
|
{
|
|
if (ShortcutButton.HasValue)
|
|
{
|
|
if (button == ShortcutButton.Value)
|
|
{
|
|
_pressedDownByGamepadShortcut = true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>Called when a button on the gamepad has been released</summary>
|
|
/// <param name="button">Button that has been released</param>
|
|
protected override void OnButtonReleased(Buttons button)
|
|
{
|
|
if (ShortcutButton.HasValue)
|
|
{
|
|
if (_pressedDownByGamepadShortcut)
|
|
{
|
|
if (button == ShortcutButton.Value)
|
|
{
|
|
_pressedDownByGamepadShortcut = false;
|
|
if (!Depressed)
|
|
OnPressed();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Called when a key on the keyboard has been pressed down</summary>
|
|
/// <param name="keyCode">Code of the key that was pressed</param>
|
|
/// <returns>
|
|
/// True if the key press was handled by the control, otherwise false.
|
|
/// </returns>
|
|
protected override bool OnKeyPressed(Keys keyCode)
|
|
{
|
|
if (ShortcutButton.HasValue)
|
|
{
|
|
if (keyCode == KeyFromButton(ShortcutButton.Value))
|
|
{
|
|
_pressedDownByKeyboardShortcut = true;
|
|
return true;
|
|
}
|
|
}
|
|
if (HasFocus)
|
|
{
|
|
if (keyCode == Keys.Space)
|
|
{
|
|
_pressedDownByKeyboard = true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>Called when a key on the keyboard has been released again</summary>
|
|
/// <param name="keyCode">Code of the key that was released</param>
|
|
protected override void OnKeyReleased(Keys keyCode)
|
|
{
|
|
if (_pressedDownByKeyboardShortcut)
|
|
{
|
|
if (ShortcutButton.HasValue)
|
|
{
|
|
if (keyCode == KeyFromButton(ShortcutButton.Value))
|
|
{
|
|
_pressedDownByKeyboardShortcut = false;
|
|
if (!Depressed)
|
|
OnPressed();
|
|
}
|
|
}
|
|
}
|
|
if (_pressedDownByKeyboard)
|
|
{
|
|
if (keyCode == Keys.Space)
|
|
{
|
|
_pressedDownByKeyboard = false;
|
|
if (!Depressed)
|
|
OnPressed();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Called when the control is pressed</summary>
|
|
/// <remarks>
|
|
/// If you were to implement a button, for example, you could trigger a 'Pressed'
|
|
/// event here are call a user-provided delegate, depending on your design.
|
|
/// </remarks>
|
|
protected virtual void OnPressed()
|
|
{
|
|
}
|
|
|
|
/// <summary>Looks up the equivalent key to the gamepad button</summary>
|
|
/// <param name="button">
|
|
/// Gamepad button for which the equivalent key on the keyboard will be found
|
|
/// </param>
|
|
/// <returns>The key that is equivalent to the specified gamepad button</returns>
|
|
private static Keys KeyFromButton(Buttons button)
|
|
{
|
|
switch (button)
|
|
{
|
|
case Buttons.A:
|
|
{
|
|
return Keys.A;
|
|
}
|
|
case Buttons.B:
|
|
{
|
|
return Keys.B;
|
|
}
|
|
case Buttons.Back:
|
|
{
|
|
return Keys.Back;
|
|
}
|
|
case Buttons.LeftShoulder:
|
|
{
|
|
return Keys.L;
|
|
}
|
|
case Buttons.LeftStick:
|
|
{
|
|
return Keys.LeftControl;
|
|
}
|
|
case Buttons.RightShoulder:
|
|
{
|
|
return Keys.R;
|
|
}
|
|
case Buttons.RightStick:
|
|
{
|
|
return Keys.RightControl;
|
|
}
|
|
case Buttons.Start:
|
|
{
|
|
return Keys.Enter;
|
|
}
|
|
case Buttons.X:
|
|
{
|
|
return Keys.X;
|
|
}
|
|
case Buttons.Y:
|
|
{
|
|
return Keys.Y;
|
|
}
|
|
default:
|
|
{
|
|
return Keys.None;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |