#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 gestures = new Queue(); private static TouchLocation[] touches = new TouchLocation[MAX_TOUCHES]; private static TouchLocation[] prevTouches = new TouchLocation[MAX_TOUCHES]; private static List validTouches = new List(); #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 } }