Show More
Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
References:
File last commit:
Show/Diff file:
Action:
FNA/src/Input/Touch/TouchPanel.cs
233 lines | 4.7 KiB | text/x-csharp | CSharpLexer
233 lines | 4.7 KiB | text/x-csharp | CSharpLexer
r0 | #region License | |||
/* FNA - XNA4 Reimplementation for Desktop Platforms | ||||
* Copyright 2009-2020 Ethan Lee and the MonoGame Team | ||||
* | ||||
* Released under the Microsoft Public License. | ||||
* See LICENSE for details. | ||||
*/ | ||||
#endregion | ||||
#region Using Statements | ||||
using System; | ||||
using System.Collections.Generic; | ||||
#endregion | ||||
namespace Microsoft.Xna.Framework.Input.Touch | ||||
{ | ||||
// https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.touch.touchpanel.aspx | ||||
public static class TouchPanel | ||||
{ | ||||
#region Internal Constants | ||||
// The maximum number of simultaneous touches allowed by XNA. | ||||
internal const int MAX_TOUCHES = 8; | ||||
// The value that represents the absence of a finger. | ||||
internal const int NO_FINGER = -1; | ||||
#endregion | ||||
#region Public Static Properties | ||||
public static int DisplayWidth | ||||
{ | ||||
get; | ||||
set; | ||||
} | ||||
public static int DisplayHeight | ||||
{ | ||||
get; | ||||
set; | ||||
} | ||||
public static DisplayOrientation DisplayOrientation | ||||
{ | ||||
get; | ||||
set; | ||||
} | ||||
public static GestureType EnabledGestures | ||||
{ | ||||
get; | ||||
set; | ||||
} | ||||
public static bool IsGestureAvailable | ||||
{ | ||||
get | ||||
{ | ||||
return gestures.Count > 0; | ||||
} | ||||
} | ||||
public static IntPtr WindowHandle | ||||
{ | ||||
get; | ||||
set; | ||||
} | ||||
#endregion | ||||
#region Internal Static Variables | ||||
internal static bool TouchDeviceExists; | ||||
#endregion | ||||
#region Private Static Variables | ||||
private static Queue<GestureSample> gestures = new Queue<GestureSample>(); | ||||
private static TouchLocation[] touches = new TouchLocation[MAX_TOUCHES]; | ||||
private static TouchLocation[] prevTouches = new TouchLocation[MAX_TOUCHES]; | ||||
private static List<TouchLocation> validTouches = new List<TouchLocation>(); | ||||
#endregion | ||||
#region Public Static Methods | ||||
public static TouchPanelCapabilities GetCapabilities() | ||||
{ | ||||
return FNAPlatform.GetTouchCapabilities(); | ||||
} | ||||
public static TouchCollection GetState() | ||||
{ | ||||
validTouches.Clear(); | ||||
for (int i = 0; i < MAX_TOUCHES; i += 1) | ||||
{ | ||||
if (touches[i].State != TouchLocationState.Invalid) | ||||
{ | ||||
validTouches.Add(touches[i]); | ||||
} | ||||
} | ||||
return new TouchCollection(validTouches.ToArray()); | ||||
} | ||||
public static GestureSample ReadGesture() | ||||
{ | ||||
if (gestures.Count == 0) | ||||
{ | ||||
throw new InvalidOperationException(); | ||||
} | ||||
return gestures.Dequeue(); | ||||
} | ||||
#endregion | ||||
#region Internal Static Methods | ||||
internal static void EnqueueGesture(GestureSample gesture) | ||||
{ | ||||
gestures.Enqueue(gesture); | ||||
} | ||||
internal static void INTERNAL_onTouchEvent( | ||||
int fingerId, | ||||
TouchLocationState state, | ||||
float x, | ||||
float y, | ||||
float dx, | ||||
float dy | ||||
) | ||||
{ | ||||
// Calculate the scaled touch position | ||||
Vector2 touchPos = new Vector2( | ||||
(float) Math.Round(x * DisplayWidth), | ||||
(float) Math.Round(y * DisplayHeight) | ||||
); | ||||
// Notify the Gesture Detector about the event | ||||
switch (state) | ||||
{ | ||||
case TouchLocationState.Pressed: | ||||
GestureDetector.OnPressed(fingerId, touchPos); | ||||
break; | ||||
case TouchLocationState.Moved: | ||||
Vector2 delta = new Vector2( | ||||
(float) Math.Round(dx * DisplayWidth), | ||||
(float) Math.Round(dy * DisplayHeight) | ||||
); | ||||
GestureDetector.OnMoved(fingerId, touchPos, delta); | ||||
break; | ||||
case TouchLocationState.Released: | ||||
GestureDetector.OnReleased(fingerId, touchPos); | ||||
break; | ||||
} | ||||
} | ||||
internal static void SetFinger(int index, int fingerId, Vector2 fingerPos) | ||||
{ | ||||
if (fingerId == NO_FINGER) | ||||
{ | ||||
// Was there a finger here before and the user just released it? | ||||
if (prevTouches[index].State != TouchLocationState.Invalid | ||||
&& prevTouches[index].State != TouchLocationState.Released) | ||||
{ | ||||
touches[index] = new TouchLocation( | ||||
prevTouches[index].Id, | ||||
TouchLocationState.Released, | ||||
prevTouches[index].Position, | ||||
prevTouches[index].State, | ||||
prevTouches[index].Position | ||||
); | ||||
} | ||||
else | ||||
{ | ||||
/* Nothing interesting here at all. | ||||
* Insert invalid data so this element | ||||
* is not included in GetState(). | ||||
*/ | ||||
touches[index] = new TouchLocation( | ||||
NO_FINGER, | ||||
TouchLocationState.Invalid, | ||||
Vector2.Zero | ||||
); | ||||
} | ||||
return; | ||||
} | ||||
// Is this a newly pressed finger? | ||||
if (prevTouches[index].State == TouchLocationState.Invalid) | ||||
{ | ||||
touches[index] = new TouchLocation( | ||||
fingerId, | ||||
TouchLocationState.Pressed, | ||||
fingerPos | ||||
); | ||||
} | ||||
else | ||||
{ | ||||
// This finger was already down, so it's "moved" | ||||
touches[index] = new TouchLocation( | ||||
fingerId, | ||||
TouchLocationState.Moved, | ||||
fingerPos, | ||||
prevTouches[index].State, | ||||
prevTouches[index].Position | ||||
); | ||||
} | ||||
} | ||||
internal static void Update() | ||||
{ | ||||
// Update Gesture Detector for time-sensitive gestures | ||||
GestureDetector.OnUpdate(); | ||||
// Remember the last frame's touches | ||||
touches.CopyTo(prevTouches, 0); | ||||
// Get the latest finger data | ||||
FNAPlatform.UpdateTouchPanelState(); | ||||
} | ||||
#endregion | ||||
} | ||||
} | ||||