diff --git a/CHANGELOG.md b/CHANGELOG.md
index 56940ba..094f66a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,7 @@ Additions
Improvements
- Generify GenericFont's string drawing
+- Added InputHandler mouse and touch position querying that preserves the game's viewport
Fixes
- Fixed StaticSpriteBatch handling rotated sprites incorrectly
@@ -40,6 +41,7 @@ Improvements
Fixes
- Fixed paragraph links having incorrect hover locations when using special text alignments
+- Fixed the graphics device's viewport being ignored for mouse and touch queries
Removals
- Marked StyleProp equality members as obsolete
diff --git a/MLEM.Ui/Elements/ScrollBar.cs b/MLEM.Ui/Elements/ScrollBar.cs
index 4b356e6..267601a 100644
--- a/MLEM.Ui/Elements/ScrollBar.cs
+++ b/MLEM.Ui/Elements/ScrollBar.cs
@@ -137,14 +137,14 @@ namespace MLEM.Ui.Elements {
// MOUSE INPUT
var moused = this.Controls.MousedElement;
- if (moused == this && this.Controls.Input.IsMouseButtonPressed(MouseButton.Left)) {
+ if (moused == this && this.Input.IsMouseButtonPressed(MouseButton.Left)) {
this.isMouseHeld = true;
- this.scrollStartOffset = this.TransformInverseAll(this.Input.MousePosition.ToVector2()) - this.ScrollerPosition;
- } else if (this.isMouseHeld && !this.Controls.Input.IsMouseButtonDown(MouseButton.Left)) {
+ this.scrollStartOffset = this.TransformInverseAll(this.Input.ViewportMousePosition.ToVector2()) - this.ScrollerPosition;
+ } else if (this.isMouseHeld && !this.Input.IsMouseButtonDown(MouseButton.Left)) {
this.isMouseHeld = false;
}
if (this.isMouseHeld)
- this.ScrollToPos(this.TransformInverseAll(this.Input.MousePosition.ToVector2()));
+ this.ScrollToPos(this.TransformInverseAll(this.Input.ViewportMousePosition.ToVector2()));
if (!this.Horizontal && moused != null && (moused == this.Parent || moused.GetParentTree().Contains(this.Parent))) {
var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel;
if (scroll != 0)
@@ -154,7 +154,7 @@ namespace MLEM.Ui.Elements {
// TOUCH INPUT
if (!this.Horizontal) {
// are we dragging on top of the panel?
- if (this.Input.GetGesture(GestureType.VerticalDrag, out var drag)) {
+ if (this.Input.GetViewportGesture(GestureType.VerticalDrag, out var drag)) {
// if the element under the drag's start position is on top of the panel, start dragging
var touched = this.Parent.GetElementUnderPos(this.TransformInverseAll(drag.Position));
if (touched != null && touched != this)
@@ -167,11 +167,11 @@ namespace MLEM.Ui.Elements {
this.isDragging = false;
}
}
- if (this.Input.TouchState.Count <= 0) {
+ if (this.Input.ViewportTouchState.Count <= 0) {
// if no touch has occured this tick, then reset the variable
this.isTouchHeld = false;
} else {
- foreach (var loc in this.Input.TouchState) {
+ foreach (var loc in this.Input.ViewportTouchState) {
var pos = this.TransformInverseAll(loc.Position);
// if we just started touching and are on top of the scroller, then we should start scrolling
if (this.DisplayArea.Contains(pos) && !loc.TryGetPreviousLocation(out _)) {
diff --git a/MLEM.Ui/Elements/Tooltip.cs b/MLEM.Ui/Elements/Tooltip.cs
index b2b276b..c2be313 100644
--- a/MLEM.Ui/Elements/Tooltip.cs
+++ b/MLEM.Ui/Elements/Tooltip.cs
@@ -91,7 +91,7 @@ namespace MLEM.Ui.Elements {
///
public void SnapPositionToMouse() {
var viewport = this.System.Viewport;
- var offset = (this.Input.MousePosition.ToVector2() + this.MouseOffset.Value) / this.Scale;
+ var offset = (this.Input.ViewportMousePosition.ToVector2() + this.MouseOffset.Value) / this.Scale;
if (offset.X < viewport.X)
offset.X = viewport.X;
if (offset.Y < viewport.Y)
diff --git a/MLEM.Ui/UiControls.cs b/MLEM.Ui/UiControls.cs
index e376503..c0d8430 100644
--- a/MLEM.Ui/UiControls.cs
+++ b/MLEM.Ui/UiControls.cs
@@ -143,7 +143,7 @@ namespace MLEM.Ui {
// MOUSE INPUT
if (this.HandleMouse) {
- var mousedNow = this.GetElementUnderPos(this.Input.MousePosition.ToVector2());
+ var mousedNow = this.GetElementUnderPos(this.Input.ViewportMousePosition.ToVector2());
this.SetMousedElement(mousedNow);
if (this.Input.IsMouseButtonPressed(MouseButton.Left)) {
@@ -184,22 +184,22 @@ namespace MLEM.Ui {
// TOUCH INPUT
if (this.HandleTouch) {
- if (this.Input.GetGesture(GestureType.Tap, out var tap)) {
+ if (this.Input.GetViewportGesture(GestureType.Tap, out var tap)) {
this.IsAutoNavMode = false;
var tapped = this.GetElementUnderPos(tap.Position);
this.SelectElement(this.ActiveRoot, tapped);
if (tapped != null && tapped.CanBePressed)
this.System.InvokeOnElementPressed(tapped);
- } else if (this.Input.GetGesture(GestureType.Hold, out var hold)) {
+ } else if (this.Input.GetViewportGesture(GestureType.Hold, out var hold)) {
this.IsAutoNavMode = false;
var held = this.GetElementUnderPos(hold.Position);
this.SelectElement(this.ActiveRoot, held);
if (held != null && held.CanBePressed)
this.System.InvokeOnElementSecondaryPressed(held);
- } else if (this.Input.TouchState.Count <= 0) {
+ } else if (this.Input.ViewportTouchState.Count <= 0) {
this.SetTouchedElement(null);
} else {
- foreach (var location in this.Input.TouchState) {
+ foreach (var location in this.Input.ViewportTouchState) {
var element = this.GetElementUnderPos(location.Position);
if (location.State == TouchLocationState.Pressed) {
// start touching an element if we just touched down on it
diff --git a/MLEM/Input/InputHandler.cs b/MLEM/Input/InputHandler.cs
index 48ddddc..2761bcf 100644
--- a/MLEM/Input/InputHandler.cs
+++ b/MLEM/Input/InputHandler.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using MLEM.Misc;
@@ -16,7 +17,7 @@ namespace MLEM.Input {
///
/// Contains all of the gestures that have finished during the last update call.
- /// To easily query these gestures, use
+ /// To easily query these gestures, use or .
///
public readonly ReadOnlyCollection Gestures;
@@ -79,6 +80,14 @@ namespace MLEM.Input {
///
public TouchCollection TouchState { get; private set; }
///
+ /// Contains the , but with the taken into account.
+ ///
+ public IList LastViewportTouchState { get; private set; }
+ ///
+ /// Contains the , but with the taken into account.
+ ///
+ public IList ViewportTouchState { get; private set; }
+ ///
/// Contains the amount of gamepads that are currently connected.
/// This field is automatically updated in
///
@@ -92,13 +101,21 @@ namespace MLEM.Input {
///
public MouseState MouseState { get; private set; }
///
+ /// Contains the position of the mouse from the last update call, extracted from
+ ///
+ public Point LastMousePosition => this.LastMouseState.Position;
+ ///
+ /// Contains the , but with the taken into account.
+ ///
+ public Point LastViewportMousePosition => this.LastMousePosition + this.ViewportOffset;
+ ///
/// Contains the current position of the mouse, extracted from
///
public Point MousePosition => this.MouseState.Position;
///
- /// Contains the position of the mouse from the last update call, extracted from
+ /// Contains the , but with the taken into account.
///
- public Point LastMousePosition => this.LastMouseState.Position;
+ public Point ViewportMousePosition => this.MousePosition + this.ViewportOffset;
///
/// Contains the current scroll wheel value, in increments of 120
///
@@ -125,6 +142,7 @@ namespace MLEM.Input {
private readonly List inputsDownAccum = new List();
private readonly List gestures = new List();
+ private Point ViewportOffset => new Point(-this.Game.GraphicsDevice.Viewport.X, -this.Game.GraphicsDevice.Viewport.Y);
private DateTime heldKeyStart;
private DateTime lastKeyRepeat;
private bool triggerKeyRepeat;
@@ -267,7 +285,17 @@ namespace MLEM.Input {
if (this.HandleTouch) {
this.LastTouchState = this.TouchState;
+ this.LastViewportTouchState = this.ViewportTouchState;
+
this.TouchState = active ? TouchPanel.GetState() : default;
+ this.ViewportTouchState = this.TouchState;
+ if (this.ViewportTouchState.Count > 0 && this.ViewportOffset != Point.Zero) {
+ for (var i = 0; i < this.ViewportTouchState.Count; i++) {
+ var touch = this.ViewportTouchState[i];
+ touch.TryGetPreviousLocation(out var previous);
+ this.ViewportTouchState[i] = new TouchLocation(touch.Id, touch.State, touch.Position + this.ViewportOffset.ToVector2(), previous.State, previous.Position + this.ViewportOffset.ToVector2());
+ }
+ }
this.gestures.Clear();
while (active && TouchPanel.IsGestureAvailable)
@@ -512,6 +540,22 @@ namespace MLEM.Input {
return false;
}
+ ///
+ /// Queries for a gesture of the given type that finished during the current update call.
+ /// Unlike , the return value of this method takes the into account.
+ ///
+ /// The type of gesture to query for
+ /// The resulting gesture sample with the taken into account, or default if there isn't one
+ /// True if a gesture of the type was found, otherwise false
+ public bool GetViewportGesture(GestureType type, out GestureSample sample) {
+ if (this.GetGesture(type, out var original)) {
+ sample = new GestureSample(original.GestureType, original.Timestamp, original.Position + this.ViewportOffset.ToVector2(), original.Position2 + this.ViewportOffset.ToVector2(), original.Delta, original.Delta2);
+ return true;
+ }
+ sample = default;
+ return false;
+ }
+
///
/// Returns if a given control of any kind is down.
/// This is a helper function that can be passed a , or .
diff --git a/Sandbox/GameImpl.cs b/Sandbox/GameImpl.cs
index 42e6835..bf73b71 100644
--- a/Sandbox/GameImpl.cs
+++ b/Sandbox/GameImpl.cs
@@ -22,6 +22,7 @@ using MLEM.Ui;
using MLEM.Ui.Elements;
using MLEM.Ui.Style;
using MonoGame.Extended.Tiled;
+using MonoGame.Extended.ViewportAdapters;
namespace Sandbox {
public class GameImpl : MlemGame {
@@ -298,6 +299,11 @@ namespace Sandbox {
}
this.SpriteBatch.End();
};
+
+ var viewport = new BoxingViewportAdapter(this.Window, this.GraphicsDevice, 1280, 720);
+ var newPanel = new Panel(Anchor.TopLeft, new Vector2(200, 100), new Vector2(10, 10));
+ newPanel.AddChild(new Button(Anchor.TopLeft, new Vector2(100, 20), "Text", "Tooltip text"));
+ this.UiSystem.Add("Panel", newPanel);
}
protected override void DoUpdate(GameTime gameTime) {
@@ -307,7 +313,7 @@ namespace Sandbox {
var delta = this.InputHandler.ScrollWheel - this.InputHandler.LastScrollWheel;
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.ViewportMousePosition.ToVector2());
}
/*if (Input.InputsDown.Length > 0)