/// <summary> /// Performs hit testing on all captured touches and updates the hit test information. /// </summary> /// <remarks> /// This method does not require an instance of UIElement to work. /// </remarks> /// <param name="capturedTouches">Read-only collection of captured touches to test.</param> public static void HitTestCapturedTouches(ReadOnlyHitTestResultCollection capturedTouches) { // Hit test all previously captured touches. foreach (HitTestResult result in capturedTouches) { // Only hit test touches that have not already been released. if (result.StateMachine != null) { // Determine if touch is still touching the same element. UIElement element = result.StateMachine.Tag as UIElement; if (element != null) { // Hit test the captured element directly. // This makes overlayed child elements "transparent." if (element.HitTest(result.Touch, true)) { // The touch is still touching the same element. // Update the hit test information. result.SetCapturedHitTestInformation(true, element.HitTestDetails(result.Touch, true)); } else { // Touch is no longer over the capturing element. result.SetCapturedHitTestInformation(false, element.HitTestDetails(result.Touch, true)); } } else { throw new InvalidOperationException(Properties.Resources.StateMachineTagShouldBeUIElement); } } } }
/// <summary> /// Performs hit testing on all uncaptured touches and updates the hit test information. /// </summary> /// <param name="uncapturedTouches">Read-only collection of uncaptured touches to test.</param> public virtual void HitTestUncapturedTouches(ReadOnlyHitTestResultCollection uncapturedTouches) { // Hit test and assign all new touches. foreach (HitTestResult result in uncapturedTouches) { // Make sure that touch hasn't been assigned already. if (result.StateMachine != null) { continue; } // Hit test the touch to determine which object it is touching UIElement touched = HitTesting(result.Touch, false); if (touched != null) { IHitTestDetails details = touched.HitTestDetails(result.Touch, false); result.SetUncapturedHitTestInformation(touched.StateMachine, details); } else { // This touch has not been captured. result.SetUncapturedHitTestInformation(null, null); } } }
/// <summary> /// Used by the UIController to determine what UIElement is being touched by a given touch. /// </summary> /// <param name="uncapturedTouches">All touches touching the app that have not been captured.</param> /// <param name="capturedTouches">All touches touching the app that have already been captured.</param> public virtual void HitTestCallback(ReadOnlyHitTestResultCollection uncapturedTouches, ReadOnlyHitTestResultCollection capturedTouches) { HitTestCapturedTouches(capturedTouches); HitTestUncapturedTouches(uncapturedTouches); }
/// <summary> /// Used by the UIController to determine what ITouchableObject is being touched by a given touch. /// </summary> /// <param name="uncapturedTouches">All touches touching the app that have not been captured.</param> /// <param name="capturedTouches">All touches touching the app that have already been captured.</param> private void HitTestCallback(ReadOnlyHitTestResultCollection uncapturedTouches, ReadOnlyHitTestResultCollection capturedTouches) { // Hit test and assign all new touches foreach (HitTestResult result in uncapturedTouches) { // Hit test the touch to determine which object it is touching UIElementStateMachine touched = HitTest(result.Touch); if (touched != null) { // Only using state machines to do capture, not to track touch position inside the object, // so just use (0, 0) XnaScatterHitTestDetails details = new XnaScatterHitTestDetails(0, 0); // Set the hit test details result.SetUncapturedHitTestInformation(touched, details); } else { // Must call SetUncapturedHitTestInformation, but since nothing was touched, pass null result.SetUncapturedHitTestInformation(null, null); } } // Hit test all previously captured touches foreach (HitTestResult result in capturedTouches) { // Only using state machines to do capture, not to track touch position inside the object, // so just use (0, 0) XnaScatterHitTestDetails details = new XnaScatterHitTestDetails(0, 0); // Set the hit test details result.SetCapturedHitTestInformation(true, details); } }
/// <summary> /// Performs hit testing for all game components. /// </summary> private void HitTestCallback(ReadOnlyHitTestResultCollection uncapturedTouches, ReadOnlyHitTestResultCollection capturedTouches) { // First check captured touches. UIElement.HitTestCapturedTouches(capturedTouches); // Now test the uncaptured touches. // The order is important for overlapping elements. // Test from front to back (reverse of DrawOrder). // Test the HUD elements first hudContainer.HitTestUncapturedTouches(uncapturedTouches); // Now the textiles. textiles.HitTestUncapturedTouches(uncapturedTouches); SetActiveTouches(); // And finally the background canvas. meshCanvas.HitTestUncapturedTouches(uncapturedTouches); }
/// <summary> /// Calls the users HitTestCallback delegate passing the unpackaged touches. /// </summary> private void HitTestNonCapturedTouches() { // Don't try to do hit testing if there are no touches to test. if (this.unpackagedTouches.Count == 0 && this.packagedTouches.Count == 0) { return; } ReadOnlyHitTestResultCollection uncapturedHitTestResults = new ReadOnlyHitTestResultCollection(this.unpackagedTouches); ReadOnlyHitTestResultCollection capturedHitTestResults = new ReadOnlyHitTestResultCollection(this.packagedTouches); // We want to remove the packed touches such that all touches must be re-added. this.packagedTouches.Clear(); Debug.Assert(hitTestCallback != null, "The HitTestCallBack is null"); // Call the user HitTestCallback delegate. this.hitTestCallback(uncapturedHitTestResults, capturedHitTestResults); // Check the capturedTouchResults to see if they were hit Tested successfully foreach (HitTestResult capturedHitTestResult in capturedHitTestResults) { PostHitTestResult(capturedHitTestResult); } foreach (HitTestResult hitTestResult in uncapturedHitTestResults) { PostHitTestResult(hitTestResult); } }
/// <summary> /// Performs hit testing on all captured contacts and updates the hit test information. /// </summary> /// <remarks> /// This method does not require an instance of UIElement to work. /// </remarks> /// <param name="capturedContacts">Read-only collection of captured contacts to test.</param> public static void HitTestCapturedContacts(ReadOnlyHitTestResultCollection capturedContacts) { // Hit test all previously captured contacts. foreach (HitTestResult result in capturedContacts) { // Only hit test contacts that have not already been released. if (result.StateMachine != null) { // Determine if contact is still touching the same element. UIElement element = result.StateMachine.Tag as UIElement; if (element != null) { // Hit test the captured element directly. // This makes overlayed child elements "transparent." if (element.HitTest(result.Contact, true)) { // The contact is still touching the same element. // Update the hit test information. result.SetCapturedHitTestInformation(true, element.HitTestDetails(result.Contact, true)); } else { // Contact is no longer over the capturing element. result.SetCapturedHitTestInformation(false, element.HitTestDetails(result.Contact, true)); } } else { throw new InvalidOperationException("stateMachine.Tag is expected to reference a UIElement."); } } } }