Ejemplo n.º 1
0
        private bool ProcessDoubleTap(TouchLocation touch)
        {
            if (!GestureIsEnabled(GestureType.DoubleTap) || _tapDisabled || _lastTap.State == TouchLocationState.Invalid)
            {
                return(false);
            }

            // If the new tap is too far away from the last then
            // this cannot be a double tap event.
            var dist = Vector2.Distance(touch.Position, _lastTap.Position);

            if (dist > TapJitterTolerance)
            {
                return(false);
            }

            // Check that this tap happened within the standard
            // double tap time threshold of 300 milliseconds.
            var elapsed = touch.Timestamp - _lastTap.Timestamp;

            if (elapsed.TotalMilliseconds > 300)
            {
                return(false);
            }

            GestureList.Enqueue(new GestureSample(
                                    GestureType.DoubleTap, touch.Timestamp,
                                    touch.Position, Vector2.Zero,
                                    Vector2.Zero, Vector2.Zero));

            // Disable taps until after the next release.
            _tapDisabled = true;

            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Apply the given new touch to the state. If it is a Pressed it will be added as a new touch, otherwise we update the existing touch it matches
        /// </summary>
        private void ApplyTouch(List <TouchLocation> state, TouchLocation touch)
        {
            if (touch.State == TouchLocationState.Pressed)
            {
                state.Add(touch);
                return;
            }

            //Find the matching touch
            for (var i = 0; i < state.Count; i++)
            {
                var existingTouch = state[i];

                if (existingTouch.Id == touch.Id)
                {
                    //If we are moving straight from Pressed to Released and we've existed for multiple frames, that means we've never been seen, so just get rid of us
                    if (existingTouch.State == TouchLocationState.Pressed && touch.State == TouchLocationState.Released && existingTouch.PressTimestamp != touch.Timestamp)
                    {
                        state.RemoveAt(i);
                    }
                    else
                    {
                        //Otherwise update the touch based on the new one
                        existingTouch.UpdateState(touch);
                        state[i] = existingTouch;
                    }

                    break;
                }
            }
        }
Ejemplo n.º 3
0
        private void ProcessTap(TouchLocation touch)
        {
            if (_tapDisabled)
            {
                return;
            }

            // If the release is too far away from the press
            // position then this cannot be a tap event.
            var dist = Vector2.Distance(touch.PressPosition, touch.Position);

            if (dist > TapJitterTolerance)
            {
                return;
            }

            // If we pressed and held too long then don't
            // generate a tap event for it.
            var elapsed = CurrentTimestamp - touch.PressTimestamp;

            if (elapsed > TimeRequiredForHold)
            {
                return;
            }

            // Store the last tap for
            // double tap processing.
            _lastTap = touch;

            // Fire off the tap event immediately.
            if (GestureIsEnabled(GestureType.Tap))
            {
                var tap = new GestureSample(
                    GestureType.Tap, touch.Timestamp,
                    touch.Position, Vector2.Zero,
                    Vector2.Zero, Vector2.Zero);
                GestureList.Enqueue(tap);
            }
        }
Ejemplo n.º 4
0
        private void ProcessHold(TouchLocation touch)
        {
            if (!GestureIsEnabled(GestureType.Hold) || _holdDisabled)
            {
                return;
            }

            var elapsed = CurrentTimestamp - touch.PressTimestamp;

            if (elapsed < TimeRequiredForHold)
            {
                return;
            }

            _holdDisabled = true;

            GestureList.Enqueue(
                new GestureSample(GestureType.Hold,
                                  touch.Timestamp,
                                  touch.Position, Vector2.Zero,
                                  Vector2.Zero, Vector2.Zero));
        }
Ejemplo n.º 5
0
        private void ProcessDrag(TouchLocation touch)
        {
            var dragH = GestureIsEnabled(GestureType.HorizontalDrag);
            var dragV = GestureIsEnabled(GestureType.VerticalDrag);
            var dragF = GestureIsEnabled(GestureType.FreeDrag);

            if (!dragH && !dragV && !dragF)
            {
                return;
            }

            // Make sure this is a move event and that we have
            // a previous touch location.
            TouchLocation prevTouch;

            if (touch.State != TouchLocationState.Moved || !touch.TryGetPreviousLocation(out prevTouch))
            {
                return;
            }

            var delta = touch.Position - prevTouch.Position;

            // If we're free dragging then stick to it.
            if (_dragGestureStarted != GestureType.FreeDrag)
            {
                var isHorizontalDelta = Math.Abs(delta.X) > Math.Abs(delta.Y * 2.0f);
                var isVerticalDelta   = Math.Abs(delta.Y) > Math.Abs(delta.X * 2.0f);
                var classify          = _dragGestureStarted == GestureType.None;

                // Once we enter either vertical or horizontal drags
                // we stick to it... regardless of the delta.
                if (dragH && ((classify && isHorizontalDelta) || _dragGestureStarted == GestureType.HorizontalDrag))
                {
                    delta.Y             = 0;
                    _dragGestureStarted = GestureType.HorizontalDrag;
                }
                else if (dragV && ((classify && isVerticalDelta) || _dragGestureStarted == GestureType.VerticalDrag))
                {
                    delta.X             = 0;
                    _dragGestureStarted = GestureType.VerticalDrag;
                }

                // If the delta isn't either horizontal or vertical
                //then it could be a free drag if not classified.
                else if (dragF && classify)
                {
                    _dragGestureStarted = GestureType.FreeDrag;
                }
                else
                {
                    // If we couldn't classify the drag then
                    // it is nothing... set it to complete.
                    _dragGestureStarted = GestureType.DragComplete;
                }
            }

            // If the drag could not be classified then no gesture.
            if (_dragGestureStarted == GestureType.None || _dragGestureStarted == GestureType.DragComplete)
            {
                return;
            }

            _tapDisabled  = true;
            _holdDisabled = true;

            GestureList.Enqueue(new GestureSample(
                                    _dragGestureStarted, touch.Timestamp,
                                    touch.Position, Vector2.Zero,
                                    delta, Vector2.Zero));
        }
Ejemplo n.º 6
0
        internal void AddEvent(int id, TouchLocationState state, Vector2 position, bool isMouse)
        {
            // Different platforms return different touch identifiers
            // based on the specifics of their implementation and the
            // system drivers.
            //
            // Sometimes these ids are suitable for our use, but other
            // times it can recycle ids or do cute things like return
            // the same id for double tap events.
            //
            // We instead provide consistent ids by generating them
            // ourselves on the press and looking them up on move
            // and release events.
            //
            if (state == TouchLocationState.Pressed)
            {
                if (isMouse)
                {
                    // Mouse pointing devices always use a reserved Id
                    _touchIds[id] = MouseTouchId;
                }
                else
                {
                    _touchIds[id] = _nextTouchId++;
                }
            }

            // Try to find the touch id.
            int touchId;

            if (!_touchIds.TryGetValue(id, out touchId))
            {
                // If we got here that means either the device is sending
                // us bad, out of order, or old touch events.  In any case
                // just ignore them.
                return;
            }

            if (!isMouse || EnableMouseTouchPoint || EnableMouseGestures)
            {
                // Add the new touch event keeping the list from getting
                // too large if no one happens to be requesting the state.
                var evt = new TouchLocation(touchId, state, position * _touchScale, CurrentTimestamp);

                if (!isMouse || EnableMouseTouchPoint)
                {
                    ApplyTouch(_touchState, evt);
                }

                //If we have gestures enabled then collect events for those too.
                //We also have to keep tracking any touches while we know about touches so we don't miss releases even if gesture recognition is disabled
                if ((EnabledGestures != GestureType.None || _gestureState.Count > 0) && (!isMouse || EnableMouseGestures))
                {
                    ApplyTouch(_gestureState, evt);

                    if (EnabledGestures != GestureType.None)
                    {
                        UpdateGestures(true);
                    }

                    AgeTouches(_gestureState);
                }
            }

            // If this is a release unmap the hardware id.
            if (state == TouchLocationState.Released)
            {
                _touchIds.Remove(id);
            }
        }