mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-12-25 01:39:23 +01:00
Improved gamepad navigation by employing angles between elements
This commit is contained in:
parent
cb8fed87e5
commit
45955bb5e8
2 changed files with 15 additions and 30 deletions
|
@ -46,6 +46,7 @@ Improvements
|
|||
- Allow setting a default color for clickable links in UiStyle
|
||||
- Allow ElementHelper's KeybindButton to query a combination at a given index
|
||||
- Automatically select the first element when a dropdown is opened in auto nav mode
|
||||
- Improved gamepad navigation by employing angles between elements
|
||||
|
||||
Fixes
|
||||
- Fixed paragraph links having incorrect hover locations when using special text alignments
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using Microsoft.Xna.Framework.Input.Touch;
|
||||
using MLEM.Extensions;
|
||||
using MLEM.Input;
|
||||
using MLEM.Misc;
|
||||
using MLEM.Ui.Elements;
|
||||
|
@ -355,11 +357,11 @@ namespace MLEM.Ui {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next element that should be selected during gamepad navigation, based on the <see cref="RectangleF"/> that we're looking for elements in.
|
||||
/// Returns the next element that should be selected during gamepad navigation, based on the <see cref="Direction2"/> that we're looking for elements in.
|
||||
/// </summary>
|
||||
/// <param name="searchArea">The area that we're looking for next elements in</param>
|
||||
/// <param name="direction">The direction that we're looking for next elements in</param>
|
||||
/// <returns>The first element found in that area</returns>
|
||||
protected virtual Element GetGamepadNextElement(RectangleF searchArea) {
|
||||
protected virtual Element GetGamepadNextElement(Direction2 direction) {
|
||||
if (this.ActiveRoot == null)
|
||||
return null;
|
||||
var children = this.ActiveRoot.Element.GetChildren(c => !c.IsHidden, true, true).Append(this.ActiveRoot.Element);
|
||||
|
@ -367,14 +369,17 @@ namespace MLEM.Ui {
|
|||
return children.FirstOrDefault(c => c.CanBeSelected);
|
||||
} else {
|
||||
Element closest = null;
|
||||
float closestDist = 0;
|
||||
float closestDistSq = 0;
|
||||
foreach (var child in children) {
|
||||
if (!child.CanBeSelected || child == this.SelectedElement || !searchArea.Intersects(child.Area))
|
||||
if (!child.CanBeSelected || child == this.SelectedElement)
|
||||
continue;
|
||||
var dist = Vector2.Distance(child.Area.Center, this.SelectedElement.Area.Center);
|
||||
if (closest == null || dist < closestDist) {
|
||||
var distVec = child.Area.Center - this.SelectedElement.Area.Center;
|
||||
if (Math.Abs(direction.Angle() - Math.Atan2(distVec.Y, distVec.X)) >= MathHelper.PiOver2 - Element.Epsilon)
|
||||
continue;
|
||||
var distSq = distVec.LengthSquared();
|
||||
if (closest == null || distSq < closestDistSq) {
|
||||
closest = child;
|
||||
closestDist = dist;
|
||||
closestDistSq = distSq;
|
||||
}
|
||||
}
|
||||
return closest;
|
||||
|
@ -383,28 +388,7 @@ namespace MLEM.Ui {
|
|||
|
||||
private void HandleGamepadNextElement(Direction2 dir) {
|
||||
this.IsAutoNavMode = true;
|
||||
RectangleF searchArea = default;
|
||||
if (this.SelectedElement?.Root != null) {
|
||||
searchArea = this.SelectedElement.Area;
|
||||
var (_, _, width, height) = this.System.Viewport;
|
||||
switch (dir) {
|
||||
case Direction2.Down:
|
||||
searchArea.Height += height;
|
||||
break;
|
||||
case Direction2.Left:
|
||||
searchArea.X -= width;
|
||||
searchArea.Width += width;
|
||||
break;
|
||||
case Direction2.Right:
|
||||
searchArea.Width += width;
|
||||
break;
|
||||
case Direction2.Up:
|
||||
searchArea.Y -= height;
|
||||
searchArea.Height += height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var next = this.GetGamepadNextElement(searchArea);
|
||||
var next = this.GetGamepadNextElement(dir);
|
||||
if (this.SelectedElement != null)
|
||||
next = this.SelectedElement.GetGamepadNextElement(dir, next);
|
||||
if (next != null)
|
||||
|
|
Loading…
Reference in a new issue