MultiTouchSystemGestureLogic.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Input / Stylus / MultiTouchSystemGestureLogic.cs / 1305600 / MultiTouchSystemGestureLogic.cs

                            //---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
//--------------------------------------------------------------------------- 

using System; 
using System.Diagnostics; 

namespace System.Windows.Input 
{
    /// 
    ///     Handles detection of TwoFingerTap and Rollover static gestures.
    ///  
    internal class MultiTouchSystemGestureLogic
    { 
        internal MultiTouchSystemGestureLogic() 
        {
            _currentState = State.Idle; 
            Reset();
        }

        ///  
        ///     Analyzes stylus input and determines if a SystemGesture should be generated.
        ///  
        /// The latest stylus input report. 
        /// The SystemGesture to generate, null otherwise.
        internal SystemGesture? GenerateStaticGesture(RawStylusInputReport stylusInputReport) 
        {
            switch (stylusInputReport.Actions)
            {
                case RawStylusActions.Down: 
                    OnTouchDown(stylusInputReport);
                    return null; 
 
                case RawStylusActions.Up:
                    return OnTouchUp(stylusInputReport); 


                case RawStylusActions.SystemGesture:
                    OnSystemGesture((RawStylusSystemGestureInputReport)stylusInputReport); 
                    return null;
 
                    /* 
                case RawStylusActions.Move:
                case RawStylusActions.Activate: 
                case RawStylusActions.Deactivate:
                case RawStylusActions.OutOfRange:
                    return null;
                     */ 

                default: 
                    return null; 
            }
        } 

        private void OnTouchDown(RawStylusInputReport stylusInputReport)
        {
            switch (_currentState) 
            {
                case State.Idle: 
                    // The first finger came down 
                    Reset(); // Clear old settings
                    _firstStylusDeviceId = stylusInputReport.StylusDeviceId; 
                    _currentState = State.OneFingerDown;
                    _firstDownTime = Environment.TickCount;
                    break;
 
                case State.OneFingerDown:
                    // The second finger came down 
                    Debug.Assert(_firstStylusDeviceId != null && _firstStylusDeviceId != stylusInputReport.StylusDeviceId); 
                    Debug.Assert(_secondStylusDeviceId == null);
                    _secondStylusDeviceId = stylusInputReport.StylusDeviceId; 
                    _currentState = State.TwoFingersDown;
                    break;

                    // Ignoring fingers beyond two 
            }
        } 
 
        private SystemGesture? OnTouchUp(RawStylusInputReport stylusInputReport)
        { 
            switch (_currentState)
            {
                case State.TwoFingersDown:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId)) 
                    {
                        // One of the two fingers released 
                        _firstUpTime = Environment.TickCount; 
                        _currentState = State.OneFingerInStaticGesture;
                    } 
                    break;

                case State.OneFingerDown:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId)) 
                    {
                        // The single finger that was down was released 
                        _currentState = State.Idle; 
                    }
                    break; 

                case State.OneFingerInStaticGesture:
                    // The last of two fingers released
                    _currentState = State.Idle; 

                    // Check the times and see if a TwoFingerTap or Rollover should be generated. 
                    // TwoFingerTap is more constrained than Rollover, so check it first. 
                    if (IsTwoFingerTap())
                    { 
                        return SystemGesture.TwoFingerTap;
                    }
#if ROLLOVER_IMPLEMENTED
                    else if (IsRollover()) 
                    {
                        return SystemGesture.Rollover; 
                    } 
#endif
                    break; 

                case State.TwoFingersInWisptisGesture:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                    { 
                        // One of the two fingers released.
                        _currentState = State.OneFingerInWisptisGesture; 
                    } 
                    break;
 
                case State.OneFingerInWisptisGesture:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                    {
                        // The last finger released 
                        _currentState = State.Idle;
                    } 
                    break; 

            } 

            return null;
        }
 
        private void OnSystemGesture(RawStylusSystemGestureInputReport stylusInputReport)
        { 
            switch (_currentState) 
            {
                case State.TwoFingersDown: 
                    switch (stylusInputReport.SystemGesture)
                    {
                        case SystemGesture.Drag:
                        case SystemGesture.RightDrag: 
                        case SystemGesture.Flick:
                            // One of the two fingers made a Wisptis detected gesture 
                            // that prevents TwoFingerTap or Rollover. 
                            _currentState = State.TwoFingersInWisptisGesture;
                            break; 
                    }
                    break;

                case State.OneFingerInStaticGesture: 
                case State.OneFingerDown:
                    switch (stylusInputReport.SystemGesture) 
                    { 
                        case SystemGesture.Drag:
                        case SystemGesture.RightDrag: 
                        case SystemGesture.Flick:
                            // A finger made a Wisptis detected gesture
                            // that prevents TwoFingerTap or Rollover.
                            _currentState = State.OneFingerInWisptisGesture; 
                            break;
                    } 
                    break; 
            }
        } 

        private void Reset()
        {
            _firstStylusDeviceId = null; 
            _secondStylusDeviceId = null;
            _firstDownTime = 0; 
            _firstUpTime = 0; 
        }
 
        private bool IsTrackedStylusId(int id)
        {
            return (id == _firstStylusDeviceId) || (id == _secondStylusDeviceId);
        } 

        private bool IsTwoFingerTap() 
        { 
            int now = Environment.TickCount;
            int sinceFirstDown = now - _firstDownTime; 
            int sinceFirstUp = now - _firstUpTime;
            return (sinceFirstUp < TwoFingerTapTime) && (sinceFirstDown < RolloverTime);
        }
 
#if ROLLOVER_IMPLEMENTED
        private bool IsRollover() 
        { 
            int sinceFirstDown = Environment.TickCount - _firstDownTime;
            return sinceFirstDown < RolloverTime; 
        }
#endif

        private State _currentState; 
        private int? _firstStylusDeviceId;
        private int? _secondStylusDeviceId; 
        private int _firstDownTime; 
        private int _firstUpTime;
 
        //


        private const int TwoFingerTapTime = 150; 
        private const int RolloverTime = 1158;
 
        private enum State 
        {
            Idle, 
            OneFingerDown,
            TwoFingersDown,
            OneFingerInStaticGesture,
            TwoFingersInWisptisGesture, 
            OneFingerInWisptisGesture,
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
//--------------------------------------------------------------------------- 

using System; 
using System.Diagnostics; 

namespace System.Windows.Input 
{
    /// 
    ///     Handles detection of TwoFingerTap and Rollover static gestures.
    ///  
    internal class MultiTouchSystemGestureLogic
    { 
        internal MultiTouchSystemGestureLogic() 
        {
            _currentState = State.Idle; 
            Reset();
        }

        ///  
        ///     Analyzes stylus input and determines if a SystemGesture should be generated.
        ///  
        /// The latest stylus input report. 
        /// The SystemGesture to generate, null otherwise.
        internal SystemGesture? GenerateStaticGesture(RawStylusInputReport stylusInputReport) 
        {
            switch (stylusInputReport.Actions)
            {
                case RawStylusActions.Down: 
                    OnTouchDown(stylusInputReport);
                    return null; 
 
                case RawStylusActions.Up:
                    return OnTouchUp(stylusInputReport); 


                case RawStylusActions.SystemGesture:
                    OnSystemGesture((RawStylusSystemGestureInputReport)stylusInputReport); 
                    return null;
 
                    /* 
                case RawStylusActions.Move:
                case RawStylusActions.Activate: 
                case RawStylusActions.Deactivate:
                case RawStylusActions.OutOfRange:
                    return null;
                     */ 

                default: 
                    return null; 
            }
        } 

        private void OnTouchDown(RawStylusInputReport stylusInputReport)
        {
            switch (_currentState) 
            {
                case State.Idle: 
                    // The first finger came down 
                    Reset(); // Clear old settings
                    _firstStylusDeviceId = stylusInputReport.StylusDeviceId; 
                    _currentState = State.OneFingerDown;
                    _firstDownTime = Environment.TickCount;
                    break;
 
                case State.OneFingerDown:
                    // The second finger came down 
                    Debug.Assert(_firstStylusDeviceId != null && _firstStylusDeviceId != stylusInputReport.StylusDeviceId); 
                    Debug.Assert(_secondStylusDeviceId == null);
                    _secondStylusDeviceId = stylusInputReport.StylusDeviceId; 
                    _currentState = State.TwoFingersDown;
                    break;

                    // Ignoring fingers beyond two 
            }
        } 
 
        private SystemGesture? OnTouchUp(RawStylusInputReport stylusInputReport)
        { 
            switch (_currentState)
            {
                case State.TwoFingersDown:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId)) 
                    {
                        // One of the two fingers released 
                        _firstUpTime = Environment.TickCount; 
                        _currentState = State.OneFingerInStaticGesture;
                    } 
                    break;

                case State.OneFingerDown:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId)) 
                    {
                        // The single finger that was down was released 
                        _currentState = State.Idle; 
                    }
                    break; 

                case State.OneFingerInStaticGesture:
                    // The last of two fingers released
                    _currentState = State.Idle; 

                    // Check the times and see if a TwoFingerTap or Rollover should be generated. 
                    // TwoFingerTap is more constrained than Rollover, so check it first. 
                    if (IsTwoFingerTap())
                    { 
                        return SystemGesture.TwoFingerTap;
                    }
#if ROLLOVER_IMPLEMENTED
                    else if (IsRollover()) 
                    {
                        return SystemGesture.Rollover; 
                    } 
#endif
                    break; 

                case State.TwoFingersInWisptisGesture:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                    { 
                        // One of the two fingers released.
                        _currentState = State.OneFingerInWisptisGesture; 
                    } 
                    break;
 
                case State.OneFingerInWisptisGesture:
                    if (IsTrackedStylusId(stylusInputReport.StylusDeviceId))
                    {
                        // The last finger released 
                        _currentState = State.Idle;
                    } 
                    break; 

            } 

            return null;
        }
 
        private void OnSystemGesture(RawStylusSystemGestureInputReport stylusInputReport)
        { 
            switch (_currentState) 
            {
                case State.TwoFingersDown: 
                    switch (stylusInputReport.SystemGesture)
                    {
                        case SystemGesture.Drag:
                        case SystemGesture.RightDrag: 
                        case SystemGesture.Flick:
                            // One of the two fingers made a Wisptis detected gesture 
                            // that prevents TwoFingerTap or Rollover. 
                            _currentState = State.TwoFingersInWisptisGesture;
                            break; 
                    }
                    break;

                case State.OneFingerInStaticGesture: 
                case State.OneFingerDown:
                    switch (stylusInputReport.SystemGesture) 
                    { 
                        case SystemGesture.Drag:
                        case SystemGesture.RightDrag: 
                        case SystemGesture.Flick:
                            // A finger made a Wisptis detected gesture
                            // that prevents TwoFingerTap or Rollover.
                            _currentState = State.OneFingerInWisptisGesture; 
                            break;
                    } 
                    break; 
            }
        } 

        private void Reset()
        {
            _firstStylusDeviceId = null; 
            _secondStylusDeviceId = null;
            _firstDownTime = 0; 
            _firstUpTime = 0; 
        }
 
        private bool IsTrackedStylusId(int id)
        {
            return (id == _firstStylusDeviceId) || (id == _secondStylusDeviceId);
        } 

        private bool IsTwoFingerTap() 
        { 
            int now = Environment.TickCount;
            int sinceFirstDown = now - _firstDownTime; 
            int sinceFirstUp = now - _firstUpTime;
            return (sinceFirstUp < TwoFingerTapTime) && (sinceFirstDown < RolloverTime);
        }
 
#if ROLLOVER_IMPLEMENTED
        private bool IsRollover() 
        { 
            int sinceFirstDown = Environment.TickCount - _firstDownTime;
            return sinceFirstDown < RolloverTime; 
        }
#endif

        private State _currentState; 
        private int? _firstStylusDeviceId;
        private int? _secondStylusDeviceId; 
        private int _firstDownTime; 
        private int _firstUpTime;
 
        //


        private const int TwoFingerTapTime = 150; 
        private const int RolloverTime = 1158;
 
        private enum State 
        {
            Idle, 
            OneFingerDown,
            TwoFingersDown,
            OneFingerInStaticGesture,
            TwoFingersInWisptisGesture, 
            OneFingerInWisptisGesture,
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK