1
0
Fork 0
mirror of https://github.com/Ellpeck/MLEM.git synced 2024-05-23 00:53:37 +02:00

added gamepad controls

This commit is contained in:
Ellpeck 2019-09-09 16:25:07 +02:00
parent 3f0e0cf6d3
commit c52c9825f0
2 changed files with 71 additions and 3 deletions

View file

@ -5,7 +5,7 @@
<PropertyGroup>
<Authors>Ellpeck</Authors>
<Description>A mouse, keyboard and touch ready Ui system that features automatic anchoring, sizing and several ready-to-use element types. Part of (M)LEM (L)ibrary by (E)llpeck for (M)onoGame</Description>
<Description>A mouse, keyboard, gamepad and touch ready Ui system that features automatic anchoring, sizing and several ready-to-use element types. Part of (M)LEM (L)ibrary by (E)llpeck for (M)onoGame</Description>
<PackageTags>monogame ellpeck mlem ui user interface graphical gui system</PackageTags>
<PackageProjectUrl>https://github.com/Ellpeck/MLEM</PackageProjectUrl>
<RepositoryUrl>https://github.com/Ellpeck/MLEM</RepositoryUrl>

View file

@ -5,6 +5,7 @@ using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using MLEM.Extensions;
using MLEM.Input;
using MLEM.Misc;
using MLEM.Ui.Elements;
namespace MLEM.Ui {
@ -18,6 +19,10 @@ namespace MLEM.Ui {
public Element SelectedElement { get; private set; }
public bool SelectedLastElementWithMouse { get; private set; }
public Buttons[] GamepadButtons = {Buttons.A};
public Buttons[] SecondaryGamepadButtons = {Buttons.X};
public int GamepadIndex = -1;
public UiControls(UiSystem system, InputHandler inputHandler = null) {
this.system = system;
this.Input = inputHandler ?? new InputHandler();
@ -65,7 +70,7 @@ namespace MLEM.Ui {
}
} else if (this.Input.IsKeyPressed(Keys.Tab)) {
// tab or shift-tab to next or previous element
this.SelectElement(this.GetNextElement(this.Input.IsModifierKeyDown(ModifierKey.Shift)), false);
this.SelectElement(this.GetTabNextElement(this.Input.IsModifierKeyDown(ModifierKey.Shift)), false);
}
// TOUCH INPUT
@ -80,6 +85,45 @@ namespace MLEM.Ui {
if (held != null)
held.OnSecondaryPressed?.Invoke(held);
}
// GAMEPAD INPUT
else if (this.GamepadButtons.Any(b => this.Input.IsGamepadButtonPressed(b, this.GamepadIndex))) {
if (this.SelectedElement?.Root != null)
this.SelectedElement.OnPressed?.Invoke(this.SelectedElement);
} else if (this.SecondaryGamepadButtons.Any(b => this.Input.IsGamepadButtonPressed(b, this.GamepadIndex))) {
if (this.SelectedElement?.Root != null)
this.SelectedElement.OnSecondaryPressed?.Invoke(this.SelectedElement);
} else if (this.Input.IsGamepadButtonPressed(Buttons.DPadDown) || this.Input.IsGamepadButtonPressed(Buttons.LeftThumbstickDown)) {
var next = this.GetGamepadNextElement(searchArea => {
searchArea.Height += this.system.Viewport.Height;
return searchArea;
});
if (next != null)
this.SelectElement(next, false);
} else if (this.Input.IsGamepadButtonPressed(Buttons.DPadLeft) || this.Input.IsGamepadButtonPressed(Buttons.LeftThumbstickLeft)) {
var next = this.GetGamepadNextElement(searchArea => {
searchArea.X -= this.system.Viewport.Width;
searchArea.Width += this.system.Viewport.Width;
return searchArea;
});
if (next != null)
this.SelectElement(next, false);
} else if (this.Input.IsGamepadButtonPressed(Buttons.DPadRight) || this.Input.IsGamepadButtonPressed(Buttons.LeftThumbstickRight)) {
var next = this.GetGamepadNextElement(searchArea => {
searchArea.Width += this.system.Viewport.Width;
return searchArea;
});
if (next != null)
this.SelectElement(next, false);
} else if (this.Input.IsGamepadButtonPressed(Buttons.DPadUp) || this.Input.IsGamepadButtonPressed(Buttons.LeftThumbstickUp)) {
var next = this.GetGamepadNextElement(searchArea => {
searchArea.Y -= this.system.Viewport.Height;
searchArea.Height += this.system.Viewport.Height;
return searchArea;
});
if (next != null)
this.SelectElement(next, false);
}
}
public void SelectElement(Element element, bool mouse) {
@ -105,7 +149,7 @@ namespace MLEM.Ui {
return null;
}
private Element GetNextElement(bool backward) {
private Element GetTabNextElement(bool backward) {
var currRoot = this.system.GetRootElements().FirstOrDefault(root => root.CanSelectContent);
if (currRoot == null)
return null;
@ -134,5 +178,29 @@ namespace MLEM.Ui {
}
}
private Element GetGamepadNextElement(Func<Rectangle, Rectangle> searchAreaFunc) {
var currRoot = this.system.GetRootElements().FirstOrDefault(root => root.CanSelectContent);
if (currRoot == null)
return null;
var children = currRoot.Element.GetChildren(regardChildrensChildren: true).Append(currRoot.Element);
if (this.SelectedElement?.Root != currRoot) {
return children.FirstOrDefault(c => c.CanBeSelected);
} else {
var searchArea = searchAreaFunc(this.SelectedElement.Area);
Element closest = null;
float closestDist = 0;
foreach (var child in children) {
if (!child.CanBeSelected || child == this.SelectedElement || !searchArea.Intersects(child.Area))
continue;
var dist = Vector2.Distance(child.Area.Center.ToVector2(), this.SelectedElement.Area.Center.ToVector2());
if (closest == null || dist < closestDist) {
closest = child;
closestDist = dist;
}
}
return closest;
}
}
}
}