private void HitTestFail(HitTestResult hitTestResult) { IInputElementStateMachine stateMachine; // Check to see if this touch is captured to an IInputElementStateMachine. if (capturedTouches.TryGetValue(hitTestResult.Touch.Id, out stateMachine)) { if (hitTestResult.TouchTargetEvent.EventType == TouchEventType.Removed) { // Send the up notification to the old statemachine. packagedTouches.Add(hitTestResult.TouchTargetEvent, stateMachine); // Send leave notification to the old statemachine. TouchTargetEvent leaveEvent = new TouchTargetEvent(TouchEventType.Leave, hitTestResult.Touch); packagedTouches.Add(leaveEvent, stateMachine); } else { // Send the leave notification to the old statemachine. packagedTouches.Add(hitTestResult.TouchTargetEvent, stateMachine); } // If this touch was over it shouldn't be any longer. if (touchesOver.ContainsKey(hitTestResult.Touch.Id)) { touchesOver.Remove(hitTestResult.Touch.Id); } } else { // Is this touch over an IInputElementStateMachine currently? if (touchesOver.TryGetValue(hitTestResult.Touch.Id, out stateMachine)) { // The touch just moved off the edge of the IInputElementStateMachine. if (hitTestResult.TouchTargetEvent.EventType == TouchEventType.Changed) { hitTestResult.TouchTargetEvent.EventType = TouchEventType.Leave; } // Send the notification to the old statemachine. packagedTouches.Add(hitTestResult.TouchTargetEvent, stateMachine); touchesOver.Remove(hitTestResult.Touch.Id); } } // The touch isn't captured, isn't in the touches over // and it didn't hit anything so there is no where to route it. }
private void HitTestSuccess(HitTestResult hitTestResult) { if (hitTestResult.StateMachine.Controller != this) { throw SurfaceCoreFrameworkExceptions.ControllerSetToADifferentControllerException(hitTestResult.StateMachine); } // Check if the TouchId is in the touchesOver collection. IInputElementStateMachine overStateMachine; if (touchesOver.TryGetValue(hitTestResult.Touch.Id, out overStateMachine)) { // Then check if the hitTestResult is over the sane statemachine if (hitTestResult.StateMachine == overStateMachine) { // Just because the touchOver collection hasn't change doesn't mean this event is being // sent to the correct statemachine. Check if this should be sent to the captured statemachine. IInputElementStateMachine capturedStateMachine; if (capturedTouches.TryGetValue(hitTestResult.Touch.Id, out capturedStateMachine)) { if (hitTestResult.TouchTargetEvent.EventType == TouchEventType.Removed) { // Send the up notification to the old statemachine. packagedTouches.Add(hitTestResult.TouchTargetEvent, capturedStateMachine); // Send leave notification to the old statemachine. TouchTargetEvent leaveEvent = new TouchTargetEvent(TouchEventType.Leave, hitTestResult.Touch); packagedTouches.Add(leaveEvent, capturedStateMachine); } else { packagedTouches.Add(hitTestResult.TouchTargetEvent, capturedStateMachine); } } else { // Touch is not currently captured. if (hitTestResult.TouchTargetEvent.EventType == TouchEventType.Removed) { // Send the up notification to the old statemachine. packagedTouches.Add(hitTestResult.TouchTargetEvent, hitTestResult.StateMachine); // Send leave notification to the old statemachine. TouchTargetEvent leaveEvent = new TouchTargetEvent(TouchEventType.Leave, hitTestResult.Touch); packagedTouches.Add(leaveEvent, hitTestResult.StateMachine); } else { packagedTouches.Add(hitTestResult.TouchTargetEvent, hitTestResult.StateMachine); } } } else { // It's over a different statemachine. // Remove the old IInputElementStateMachine from the touchesOver collection. touchesOver.Remove(hitTestResult.Touch.Id); // Add the new IInputElementStateMachine to the touchesOver collection touchesOver.Add(hitTestResult.Touch.Id, hitTestResult.StateMachine); IInputElementStateMachine capturedStateMachine; if (capturedTouches.TryGetValue(hitTestResult.Touch.Id, out capturedStateMachine)) { // Touch is captured, but over a different statemachine. // If the touch is captured then don't send enter leave events. // Route this event to the capturedStateMachine. packagedTouches.Add(hitTestResult.TouchTargetEvent, capturedStateMachine); } else { // Touch is not captured over a new statemachine. // It's not over the same statemachine, so we need to add a leave TouchTargetEvent to tell // the statemachine its leaving. TouchTargetEvent leaveEvent = new TouchTargetEvent(TouchEventType.Leave, hitTestResult.Touch); // We need to add the leave event or it will not get routed. packagedTouches.Add(leaveEvent, overStateMachine); // Then change the EventType to Enter so that the new statemachine // will know a Touch just entered. hitTestResult.TouchTargetEvent.EventType = TouchEventType.Enter; packagedTouches.Add(hitTestResult.TouchTargetEvent, hitTestResult.StateMachine); } } } else { // Not in touchesOver. // This touch is just coming over a statemachine either change or add. // Check to see if this touch is captured to an IInputElementStateMachine. IInputElementStateMachine capturedStateMachine = null; if (capturedTouches.TryGetValue(hitTestResult.Touch.Id, out capturedStateMachine)) { // TouchesOver should reflect which element this touch is over, not which it's captured too. touchesOver.Add(hitTestResult.Touch.Id, hitTestResult.StateMachine); // We should send this event to the element that captured it. packagedTouches.Add(hitTestResult.TouchTargetEvent, capturedStateMachine); } else { // Not captured. // We want to send an Enter event instead of a changed. if (hitTestResult.TouchTargetEvent.EventType == TouchEventType.Changed) { hitTestResult.TouchTargetEvent.EventType = TouchEventType.Enter; } if (hitTestResult.TouchTargetEvent.EventType == TouchEventType.Added) { TouchTargetEvent enterEvent = new TouchTargetEvent(TouchEventType.Enter, hitTestResult.Touch); packagedTouches.Add(enterEvent, hitTestResult.StateMachine); } // This touch is now over this IInputElementStateMachine. switch (hitTestResult.TouchTargetEvent.EventType) { case TouchEventType.Enter: case TouchEventType.Added: touchesOver.Add(hitTestResult.Touch.Id, hitTestResult.StateMachine); break; case TouchEventType.Removed: case TouchEventType.Leave: Debug.Fail("If we get an removed or leave we missed adding it to an IInputElementStateMachine somewhere."); break; } packagedTouches.Add(hitTestResult.TouchTargetEvent, hitTestResult.StateMachine); } } // Route touches and remove the added ones anytime a touch Enter, Add, Remove or Leaves. RoutePackagedTouches(); packagedTouches.Clear(); }
private void PostHitTestResult(HitTestResult hitTestResult) { if (hitTestResult.StateMachine == null) { // If the model is null then the hit testing didn't find an IInputElementStateMachine // This means it's not over any models. HitTestFail(hitTestResult); } else { HitTestSuccess(hitTestResult); } }