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)); } }
private SystemGesture DetectDragOrFlick(UnsafeNativeMethods.INTERACTION_CONTEXT_OUTPUT output) { SystemGesture gesture = SystemGesture.None; if (output.interactionFlags.HasFlag(UnsafeNativeMethods.INTERACTION_FLAGS.INTERACTION_FLAG_END)) { // At the end of an interaction, any drag/flick/hold state is no longer needed _firedDrag = false; _firedHold = false; _firedFlick = false; } else { // If we have not already fired a drag/flick and we cannot be a flick if (!_firedDrag && !_firedFlick && (!_flickEngine?.Result?.CanBeFlick ?? true)) { // Convert screen pixels to inches using current DPI DpiScale dpi = VisualTreeHelper.GetDpi(_stylusDevice.CriticalActiveSource.RootVisual); double xChangeInches = output.arguments.manipulation.cumulative.translationX / dpi.PixelsPerInchX; double yChangeInches = output.arguments.manipulation.cumulative.translationY / dpi.PixelsPerInchY; // If the cumulative change is greater than our threshold // (taken from WISP, converted to inches) then fire a drag. if (xChangeInches > DragThresholdInches || yChangeInches > DragThresholdInches) { // If we have a current hold being tracked, convert to right drag gesture = (_firedHold) ? SystemGesture.RightDrag : SystemGesture.Drag; // This pointer has seen a drag _firedDrag = true; } } } return(gesture); }