/// <summary> /// Update any cursors we are displaying /// </summary> /// <param name="sender">Sender of the event</param> /// <param name="args">Event arguments</param> private void OnHandPointersUpdated(object sender, EventArgs args) { var kinectRegion = KinectRegion.GetKinectRegion(this); if (kinectRegion == null) { return; } // add the primary hand of the primary user if we need to foreach (HandPointer pointer in kinectRegion.HandPointers) { if (!pointer.IsPrimaryUser || !pointer.IsPrimaryHandOfUser) { continue; } if (!this.pointerCursorMap.ContainsKey(pointer)) { var cursor = new KinectCursor(); cursor.SetBinding(KinectCursor.CursorPressingColorProperty, new Binding("CursorPressingColor") { Source = this }); cursor.SetBinding(KinectCursor.CursorExtendedColor1Property, new Binding("CursorExtendedColor1") { Source = this }); cursor.SetBinding(KinectCursor.CursorExtendedColor2Property, new Binding("CursorExtendedColor2") { Source = this }); cursor.SetBinding(KinectCursor.CursorGrippedColor1Property, new Binding("CursorGrippedColor1") { Source = this }); cursor.SetBinding(KinectCursor.CursorGrippedColor2Property, new Binding("CursorGrippedColor2") { Source = this }); this.pointerCursorMap[pointer] = cursor; this.Children.Add(cursor); } } // check for deleted ones - either they are not in the // KinectRegion's list or they are no longer the primary var pointersToRemove = new List <HandPointer>(); foreach (HandPointer pointer in this.pointerCursorMap.Keys) { if (!kinectRegion.HandPointers.Contains(pointer) || !pointer.IsPrimaryUser || !pointer.IsPrimaryHandOfUser) { pointersToRemove.Add(pointer); } } // delete as needed foreach (HandPointer pointer in pointersToRemove) { this.Children.Remove(this.pointerCursorMap[pointer]); this.pointerCursorMap.Remove(pointer); } // update all current ones foreach (HandPointer pointer in this.pointerCursorMap.Keys) { KinectCursor cursor = this.pointerCursorMap[pointer]; // Set open state cursor.IsOpen = !pointer.IsInGripInteraction; // Get information about what this hand pointer is over bool isHovering = false; bool isOverPressTarget = false; foreach (UIElement element in pointer.EnteredElements) { if (KinectRegion.GetIsPressTarget(element)) { isHovering = true; isOverPressTarget = true; break; } if (KinectRegion.GetIsGripTarget(element)) { isHovering = true; } } // If the cursor is not over anything that considers itself pressable then don't // display any pressing progress. double adjustedPressExtent = isOverPressTarget ? pointer.PressExtent : 0.0; cursor.IsHovering = isHovering; cursor.IsPressed = isOverPressTarget && pointer.IsPressed && !pointer.IsInGripInteraction; cursor.PressExtent = adjustedPressExtent; // pointer.PressExtent has a range of 0..1 - map that to Min/Max for cursor scale double finalRadius = KinectCursor.ArtworkSize * (1.0 - (adjustedPressExtent * ((KinectCursor.MaximumCursorScale - KinectCursor.MinimumCursorScale) / 2.0))); // Compute Transforms double scaleX = finalRadius / KinectCursor.ArtworkSize; double scaleY = finalRadius / KinectCursor.ArtworkSize; // Flip hand for Left if (pointer.HandType == HandType.Left) { scaleX *= -1; } var handScale = new ScaleTransform(scaleX, scaleY); // Transform the vector art to match rendering size cursor.RenderTransform = handScale; double deltaX = (KinectCursor.ArtworkSize / 2) * scaleX; double deltaY = (KinectCursor.ArtworkSize / 2) * scaleY; // Clamp to KinectRegion bounds var cursorCanvasPosition = pointer.GetPosition(null); cursorCanvasPosition.X = Clamp(cursorCanvasPosition.X, -CursorBoundsMargin, kinectRegion.ActualWidth + CursorBoundsMargin); cursorCanvasPosition.Y = Clamp(cursorCanvasPosition.Y, -CursorBoundsMargin, kinectRegion.ActualHeight + CursorBoundsMargin); // If the cursor is not in the interactive area, show the cursor as 70% transparent cursor.Opacity = pointer.IsInteractive ? 1.0 : 0.3; Canvas.SetLeft(cursor, cursorCanvasPosition.X - deltaX); Canvas.SetTop(cursor, cursorCanvasPosition.Y - deltaY); } }
public InteractionInfo GetInteractionInfoAtLocation(int skeletonTrackingId, InteractionHandType handType, double x, double y) { var interactionInfo = new InteractionInfo { IsPressTarget = false, IsGripTarget = false, }; var hitTestPosition = InteractionZoneDefinition.InteractionZoneToElement(x, y, this.InteractionRootElement); Func <HandPointer, bool> isTargetCapturedElement = handPointer => (handPointer.TrackingId == skeletonTrackingId) && (handPointer.HandType == EnumHelper.ConvertHandType(handType)) && (handPointer.Captured != null); var targetHandPointer = this.publicHandPointers.FirstOrDefault(isTargetCapturedElement); var targetElement = targetHandPointer != null ? targetHandPointer.Captured : this.HitTest(hitTestPosition); if (targetElement != null) { // Walk up the tree and try to find a grip target and/or a press target for (DependencyObject search = targetElement; search != null && search != this.InteractionRootElement && (!interactionInfo.IsGripTarget || !interactionInfo.IsPressTarget); search = VisualTreeHelper.GetParent(search)) { var searchElement = search as FrameworkElement; if (searchElement == null) { // We need ActualWidth and Height which comes // with FrameworkElement continue; } if (!interactionInfo.IsPressTarget) { bool isPressTarget = KinectRegion.GetIsPressTarget(searchElement); if (isPressTarget) { // We found a press target. if (interactionInfo.PressTargetControlId == 0) { interactionInfo.PressTargetControlId = searchElement.GetHashCode(); } interactionInfo.IsPressTarget = true; // Apply the margin to the press target point Point pressTargetPoint = ApplyControlPressPointMargin(KinectRegion.GetPressTargetPoint(searchElement)); // Convert from interaction zone space into actual control coordinates var elementPressTargetPoint = InteractionZoneDefinition.InteractionZoneToElement( pressTargetPoint.X, pressTargetPoint.Y, searchElement); // Get it into the space of the KinectRegion var regionPressTargetPoint = searchElement.TranslatePoint(elementPressTargetPoint, this.InteractionRootElement); // Now put it into the interaction zone space but now relative to the KinectRegion var interactionPressTargetPoint = InteractionZoneDefinition.ElementToInteractionZone( regionPressTargetPoint.X, regionPressTargetPoint.Y, this.InteractionRootElement); interactionInfo.PressAttractionPointX = interactionPressTargetPoint.X; interactionInfo.PressAttractionPointY = interactionPressTargetPoint.Y; } } if (!interactionInfo.IsGripTarget) { bool isGripTarget = KinectRegion.GetIsGripTarget(searchElement); if (isGripTarget) { // We found a grip target. interactionInfo.IsGripTarget = true; } } } } return(interactionInfo); }