예제 #1
0
        private void DetectFlick(RawStylusInputReport rsir)
        {
            // Make sure the flick engine has the latest data if applicable.
            _flickEngine?.Update(rsir);

            // If we have received an up then we should check if
            // we can still be a flick.  If this is true, then fire a flick.
            if (rsir.Actions == RawStylusActions.Up &&
                (_flickEngine?.Result?.CanBeFlick ?? false))
            {
                //

                InteractionDetected?.Invoke(this,
                                            new RawStylusSystemGestureInputReport(
                                                InputMode.Foreground,
                                                Environment.TickCount,
                                                _stylusDevice.CriticalActiveSource,
                                                (Func <StylusPointDescription>)null,
                                                -1,
                                                -1,
                                                SystemGesture.Flick,
                                                Convert.ToInt32(_flickEngine.Result.TabletStart.X),
                                                Convert.ToInt32(_flickEngine.Result.TabletStart.Y),
                                                0));

                _firedFlick = true;
            }
        }
예제 #2
0
        private void Callback(IntPtr clientData, ref UnsafeNativeMethods.INTERACTION_CONTEXT_OUTPUT output)
        {
            SystemGesture gesture = SystemGesture.None;

            // Create the appropriate gesture based on interaction output
            switch (output.interactionId)
            {
            case UnsafeNativeMethods.INTERACTION_ID.INTERACTION_ID_TAP:
            {
                gesture = SystemGesture.Tap;
            }
            break;

            case UnsafeNativeMethods.INTERACTION_ID.INTERACTION_ID_SECONDARY_TAP:
            {
                gesture = SystemGesture.RightTap;
            }
            break;

            case UnsafeNativeMethods.INTERACTION_ID.INTERACTION_ID_HOLD:
            {
                _firedHold = true;

                if (output.interactionFlags.HasFlag(UnsafeNativeMethods.INTERACTION_FLAGS.INTERACTION_FLAG_BEGIN))
                {
                    gesture = SystemGesture.HoldEnter;
                }
                else
                {
                    gesture = SystemGesture.HoldLeave;
                }
            }
            break;

            case UnsafeNativeMethods.INTERACTION_ID.INTERACTION_ID_MANIPULATION:
            {
                gesture = DetectDragOrFlick(output);
            }
            break;
            }

            if (gesture != SystemGesture.None)
            {
                InteractionDetected?.Invoke(this,
                                            new RawStylusSystemGestureInputReport(
                                                InputMode.Foreground,
                                                Environment.TickCount,
                                                _stylusDevice.CriticalActiveSource,
                                                (Func <StylusPointDescription>)null,
                                                -1,
                                                -1,
                                                gesture,
                                                Convert.ToInt32(output.x),
                                                Convert.ToInt32(output.y),
                                                0));
            }
        }
예제 #3
0
        private void DetectHover()
        {
            // Hover only applies to Pen
            if (_stylusDevice.TabletDevice.Type == TabletDeviceType.Stylus)
            {
                SystemGesture gesture = SystemGesture.None;

                if (_stylusDevice.IsNew)
                {
                    // Any new stylus should automatically await hover
                    _hoverState = HoverState.AwaitingHover;
                }

                switch (_hoverState)
                {
                case HoverState.AwaitingHover:
                {
                    if (_stylusDevice.InAir)
                    {
                        // If we see an InAir while awaiting, start timing
                        _hoverStartTicks = _stylusDevice.TimeStamp;
                        _hoverState      = HoverState.TimingHover;
                    }
                }
                break;

                case HoverState.TimingHover:
                {
                    if (_stylusDevice.InAir)
                    {
                        if (_stylusDevice.TimeStamp < _hoverStartTicks)
                        {
                            // We looped over in ticks, just retry using the new ticks as the start.
                            // At worst this doubles the hover time, but it is rare and simplifies logic.
                            _hoverStartTicks = _stylusDevice.TimeStamp;
                        }
                        else if (_stylusDevice.TimeStamp - _hoverStartTicks > HoverActivationThresholdTicks)
                        {
                            // We should now activate a hover, so send HoverEnter and switch state
                            gesture     = SystemGesture.HoverEnter;
                            _hoverState = HoverState.InHover;
                        }
                    }
                    else if (_stylusDevice.IsDown)
                    {
                        // The device is no longer in air so cancel
                        _hoverState = HoverState.HoverCancelled;
                    }
                }
                break;

                case HoverState.HoverCancelled:
                {
                    if (_stylusDevice.InAir)
                    {
                        // If we are back in air post cancellation, we might need to trigger another hover
                        // so restart the state machine
                        _hoverState = HoverState.AwaitingHover;
                    }
                }
                break;

                case HoverState.InHover:
                {
                    if (_stylusDevice.IsDown || !_stylusDevice.InRange)
                    {
                        // We are cancelling a hover so send HoverLeave and switch state.
                        gesture     = SystemGesture.HoverLeave;
                        _hoverState = HoverState.HoverCancelled;
                    }
                }
                break;
                }

                if (gesture != SystemGesture.None)
                {
                    InteractionDetected?.Invoke(this,
                                                new RawStylusSystemGestureInputReport(
                                                    InputMode.Foreground,
                                                    Environment.TickCount,
                                                    _stylusDevice.CriticalActiveSource,
                                                    (Func <StylusPointDescription>)null,
                                                    -1,
                                                    -1,
                                                    gesture,
                                                    Convert.ToInt32(_stylusDevice.RawStylusPoint.X),
                                                    Convert.ToInt32(_stylusDevice.RawStylusPoint.Y),
                                                    0));
                }
            }
        }