/// <summary> /// Handles the ContactDown event. /// </summary> /// <param name="touchEvent">The contact that hit element.</param> protected override void OnTouchDown(TouchTargetEvent touchEvent) { if (textiles.ActiveTouches == null) { return; } TouchPoint contact = touchEvent.Touch; Controller.Capture(contact, this); Vector2 worldVector; if (textiles.ActiveTouches.TryGetValue(contact.Id, out worldVector)) { textiles.TextileComponent.TouchAdd(contact.Id, worldVector); } }
/// <summary> /// A contact was removed from the element. /// </summary> /// <param name="touchEvent">The contact that was removed.</param> protected override void OnTouchUp(TouchTargetEvent touchEvent) { if (textiles.ActiveTouches == null) { return; } TouchPoint contact = touchEvent.Touch; // Attempt to remove the touch regardless the touch is captured by a textile or not // since the capture must go away as a touch up event happens. textiles.TextileComponent.TryTouchRemove(contact.Id); if (TouchesCaptured.Contains(contact.Id)) { Controller.Release(contact); } }
/// <summary> /// Handles <strong>TouchUp</strong> events. /// </summary> /// <param name="touchEvent">The touch that is removed from the list box item.</param> protected override void OnTouchUp(TouchTargetEvent touchEvent) { if (TouchesCaptured.Contains(touchEvent.Touch.Id)) { // Remove the items from tracking. if (capturedItemTouchIds.ContainsKey(touchEvent.Touch.Id)) { // Get the ListBoxItem this touch is "captured" to. ListBoxStateMachineItem item = capturedItemTouchIds[touchEvent.Touch.Id]; if (ListBoxMode == ListBoxMode.Scrolling) { scrollAdapter.ProcessTouchUp(touchEvent); // Set the pressed state to false for this item. item.IsPressed = false; } else { // If in single selection mode set all the other SelectItems to unselected. if (selectionMode == SelectionMode.Single) { for (int i = 0; i < SelectedItems.Count; i++) { if (SelectedItems[i] == item) continue; SelectedItems[i].IsSelected = false; } } // Only call process touch up when the touch is captured // as it will cause the item to be select/deselected. // Also item's IsPressed state will be cleared if scrolling begins. item.ProcessCapturedTouchUp(touchEvent.Touch.Id); } // The touch is up so we don't need to track this item. capturedItemTouchIds.Remove(touchEvent.Touch.Id); touchTargetEventTouchIds.Remove(touchEvent.Touch.Id); scrollAdapterTouches.Remove(touchEvent.Touch.Id); touchChangeDeltaTouchIds.Remove(touchEvent.Touch.Id); } // Release the touch. Controller.Release(touchEvent.Touch); if (TouchesCaptured.Count == 0) { ListBoxMode = ListBoxMode.Selection; } } // Select the item if in selection mode // Release capture on the touch. base.OnTouchUp(touchEvent); }
/// <summary> /// Averages the position of the touchEvent.HitTestDetails position based on the number of touches. /// </summary> /// <param name="touchEvent">The new TouchTargetEvent</param> /// <param name="hitTestDetails">The contacEvent.HitTestDetails as ScrollViewerHitTestDetails</param> /// <param name="averageX"></param> /// <param name="averageY"></param> private void AverageTouchPosition(TouchTargetEvent touchEvent, ScrollViewerHitTestDetails hitTestDetails, out float averageX, out float averageY) { // Get the down hitTestDetails for this touch. ScrollViewerHitTestDetails downDetails = touchDownTouchInformation[touchEvent.Touch.Id].HitTestDetails as ScrollViewerHitTestDetails; // Calculate how much has changed since last move. averageX = (downDetails.HorizontalPosition - hitTestDetails.HorizontalPosition) * HorizontalViewportSize; averageY = (downDetails.VerticalPosition - hitTestDetails.VerticalPosition) * VerticalViewportSize; // Average the change by the number of touches on the Surface. averageX /= touchDownTouchInformation.Count; averageY /= touchDownTouchInformation.Count; }
/// <summary> /// Handles the TouchUp event. /// </summary> /// <param name="touchEvent"></param> public void ProcessTouchUp(TouchTargetEvent touchEvent) { if (!currentTouchInformation.ContainsKey(touchEvent.Touch.Id)) { return; } currentTouchInformation.Remove(touchEvent.Touch.Id); touchDownTouchInformation.Remove(touchEvent.Touch.Id); // Find the manipulator that is being removed. for (int i = 0; i < manipulations.Count; i++) { Manipulator2D manipulator = manipulations[i]; if (manipulator.Id == touchEvent.Touch.Id) { manipulations.Remove(manipulator); manipulatorRemoved = true; break; } } if (touchDownTouchInformation.Count == 0) { runningActualValueY = ConvertFromVerticalValueToControlSpace(verticalScrollBarStateMachine.Value); runningActualValueX = ConvertFromHorizontalValueToControlSpace(horizontalScrollBarStateMachine.Value); verticalViewportStartPosition = runningActualValueY; horizontalViewportStartPosition = runningActualValueX; OnViewportChanged(); } }
//==========================================================// /// <summary> /// Handles contact up events from the UIController. /// </summary> /// <param name="touchEvent">Event data.</param> protected override void OnTouchUp(TouchTargetEvent touchEvent) { // Release the contact Controller.Release(touchEvent.Touch); base.OnTouchUp(touchEvent); // A manipulator can't be current and removed at the same time. // Remove it from the current list before adding to removed list. currentManipulators.RemoveAll(delegate(Manipulator2D m) { return m.Id == touchEvent.Touch.Id; }); // Raise the Deactivated event if this is the last contact if (TouchesCaptured.Count < 1) { OnDeactivated(); } }
//==========================================================// /// <summary> /// Handles contact down events from the UIController. /// </summary> /// <param name="touchEvent">Event data.</param> protected override void OnTouchDown(TouchTargetEvent touchEvent) { base.OnTouchDown(touchEvent); // Capture the contact Controller.Capture(touchEvent.Touch, this); // Raise the Activated event if this is the first contact if (TouchesCaptured.Count == 1) { OnActivated(); } // Transform the contact into the screen coordinate system. Vector2 temp = Vector2.Transform(new Vector2(touchEvent.Touch.X, touchEvent.Touch.Y), Transform); currentManipulators.Add(new Manipulator2D(touchEvent.Touch.Id, temp.X, temp.Y)); }
/// <summary> /// Handles the ContactChanged event. /// </summary> /// <param name="touchEvent">The Contact that changed.</param> protected override void OnTouchMoved(TouchTargetEvent touchEvent) { // Suppress OnContactChanged events. // These will be handled in the textileComponent. }
/// <summary> /// Handles the <strong>TouchMoved</strong> event. /// </summary> /// <param name="touchEvent">The container for the touch that the event is about.</param> protected override void OnTouchMoved(TouchTargetEvent touchEvent) { base.OnTouchMoved(touchEvent); // Figure out if this touch is in the list or queue. if (capturedCollectionLookup.ContainsKey(touchEvent.Touch.Id)) { ScrollBarPart part = capturedCollectionLookup[touchEvent.Touch.Id]; // Update the hitTestDetails for this touch id. ScrollBarHitTestDetails details = touchEvent.HitTestDetails as ScrollBarHitTestDetails; if (details != null) { captureTouchesHitTestDetails[touchEvent.Touch.Id] = details; } // We only care about changes in the thumb. if (part == ScrollBarPart.Thumb) { if (!captureTouchesHitTestDetails.ContainsKey(touchEvent.Touch.Id)) { Debug.Fail("A touch changed occured on the thumb, but the touch wasn't captured"); } // Get the average position over the thumb. float averagePoint = AverageCapturedTouchesInThumbList(); // Update the value and thumb properties. Convert into Value space. UpdatedValueInValueSpace(averagePoint / (1 - viewportSize)); } } isScrolling = true; }
/// <summary> /// Handles TouchMoved events from the TouchTarget /// </summary> private void OnTouchMoved(object sender, TouchEventArgs e) { TouchTargetEvent cte = new TouchTargetEvent(TouchEventType.Changed, e.TouchPoint); lock (swapLock) { this.orderedTouchEventsBackbuffer.Enqueue(cte); if (this.orderedTouchEventsBackbuffer.Count > MaximumQueueSize) { throw SurfaceCoreFrameworkExceptions.MaximumQueueSizeReached(MaximumQueueSize); } } }
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 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. }
//==========================================================// /// <summary> /// Handles contact up events from the UIController. /// </summary> /// <param name="touchEvent">Event data.</param> protected override void OnTouchUp(TouchTargetEvent touchEvent) { // Release the contact Controller.Release(touchEvent.Touch); base.OnTouchUp(touchEvent); // A manipulator can't be current and removed at the same time. // Remove it from the current list before adding to removed list. currentManipulators.RemoveAll(delegate(Manipulator2D m) { return m.Id == touchEvent.Touch.Id; }); }
//==========================================================// /// <summary> /// Handles contact down events from the UIController. /// </summary> /// <param name="touchEvent">Event data.</param> protected override void OnTouchDown(TouchTargetEvent touchEvent) { base.OnTouchDown(touchEvent); // Capture the contact Controller.Capture(touchEvent.Touch, this); // Transform the contact into the screen coordinate system. Vector2 temp = Vector2.Transform(new Vector2(touchEvent.Touch.X, touchEvent.Touch.Y), Transform); currentManipulators.Add(new Manipulator2D(touchEvent.Touch.Id, temp.X, temp.Y)); }
/// <summary> /// Handles <strong>TouchMoved</strong> events. /// </summary> /// <param name="touchEvent">The list box item touch that changed.</param> protected override void OnTouchMoved(TouchTargetEvent touchEvent) { base.OnTouchMoved(touchEvent); if (ListBoxMode == ListBoxMode.Selection) { // Update the touch position and track total change. UpdateTouchPosition(touchEvent); // If the ListBox is in scroll mode then route this touch to the scrollAdapter. // If in selection mode check to see if the touch has moved 1/8" // and change to scrolling mode if it has. if (DidTouchMovePastThreshold(touchEvent.Touch.Id)) { ListBoxMode = ListBoxMode.Scrolling; // Uncapture touches from items and send capture // information to the ScrollViewer for every captured touches. foreach (KeyValuePair<int, TouchTargetEvent> downTouch in touchTargetEventTouchIds) { // Get the ListBoxItem this touch is "captured" to. ListBoxStateMachineItem item = capturedItemTouchIds[downTouch.Value.Touch.Id]; // Set the pressed state to false for this item. item.IsPressed = false; item.ChangeToScrolling(); item.capturedTouches.Clear(); if (!scrollAdapterTouches.Contains(downTouch.Key)) { // Track which touch ids have been added to the scroll adapter. scrollAdapterTouches.Add(downTouch.Key); // Process each touch as a touch down. scrollAdapter.ProcessTouchDown(downTouch.Value); } } } } else { // If the ListBox is scrollling then pass information to the scrollAdapter. scrollAdapter.ProcessTouchMoved(touchEvent); } }
/// <summary> /// Called when a touch that is routed to this state machine is removed. /// </summary> /// <param name="touchEvent">The container for the removed touch.</param> protected virtual void OnTouchUp(TouchTargetEvent touchEvent) { if (touchEvent.Touch == null) throw SurfaceCoreFrameworkExceptions.ArgumentNullException("touch"); if (!touchesOver.CachedTouchCollection.Contains(touchEvent.Touch.Id) && !touchesCaptured.CachedTouchCollection.Contains(touchEvent.Touch.Id)) { return; } if (touchesOver.EditableTouchCollection.Contains(touchEvent.Touch.Id)) this.touchesOver.EditableTouchCollection.Remove(touchEvent.Touch.Id); EventHandler<StateMachineTouchEventArgs> temp = TouchUp; if (temp != null) { temp(this, new StateMachineTouchEventArgs(touchEvent.Touch, this)); } if (touchesCaptured.CachedTouchCollection.Contains(touchEvent.Touch.Id)) { Controller.Release(touchEvent.Touch); } }
/// <summary> /// A contact has left the element. /// </summary> /// <param name="touchEvent">The contact that left.</param> protected override void OnTouchLeave(TouchTargetEvent touchEvent) { // Suppress OnContactLeave. }
/// <summary> /// Handles the <strong>TouchDown</strong> event. /// </summary> /// <param name="touchEvent">The container for the touch that the event is about.</param> protected override void OnTouchDown(TouchTargetEvent touchEvent) { base.OnTouchDown(touchEvent); // Did the touch hit the thumb or the track. ScrollBarPart partHit = GetScrollBarPartHit(touchEvent.HitTestDetails as ScrollBarHitTestDetails); // The touch went down on the ScrollBar so capture it. Controller.Capture(touchEvent.Touch, this); ScrollBarHitTestDetails details = touchEvent.HitTestDetails as ScrollBarHitTestDetails; // Check to make sure the details are of the correct type. // We assert because this should already be caught by HitTestResult.SetHitTestInformation. if (details == null) { Debug.Fail("touchEvent.HitTestDetails should be of type ScrollBarHitTestDetails."); return; } // Stop any flicking behavior. StopFlick(); switch (partHit) { // The Thumb was hit. case ScrollBarPart.Thumb: // Pause the animation if we are playing. if (scrollAnimation != null && scrollAnimation.IsPlaying) { scrollAnimation.Pause(); } // Set the part hit to the thumb. selectedPart = ScrollBarPart.Thumb; // Add this touch to the thumb list so that it can be used for averaging. thumbCapturedTouchesList.Add(touchEvent.Touch.Id); // Tie this touch id to the Thumb. capturedCollectionLookup.Add(touchEvent.Touch.Id, ScrollBarPart.Thumb); // We need to be able to look up the hit test details later so save that off. captureTouchesHitTestDetails.Add(touchEvent.Touch.Id, details); // We want to move the thumb from the point at which it was hit not the top, so store the offset in scrollbar space. distanceOffset.Add(touchEvent.Touch.Id, details.Position - (Value * (1 - ViewportSize))); break; // The Track was hit. case ScrollBarPart.Track: // Place the touch at the end of the track queue. trackQueue.Enqueue(touchEvent.Touch.Id); // Tie this touch to the Track. capturedCollectionLookup.Add(touchEvent.Touch.Id, ScrollBarPart.Track); // We need to be able to look up the hit test details later so save that off. captureTouchesHitTestDetails.Add(touchEvent.Touch.Id, details); // The thumb has touches captured so don't proceed. if (thumbCapturedTouchesList.Count != 0) return; int id = GetFrontOfTrackQueue(); // If the id isn't the same as touch id which went down don't proceed. if (id != touchEvent.Touch.Id) return; selectedPart = ScrollBarPart.Track; // The touch hit before the thumb. if (details.Position < ThumbStartPosition) { if (isReversed) { PageForward(); } else { PageBack(); } } else // The touch hit after the thumb { if (isReversed) { PageBack(); } else { PageForward(); } } break; default: break; } }
/// <summary> /// Handles the <strong>TouchUp</strong> event. /// </summary> /// <param name="touchEvent">The container for the touch that the event is about.</param> protected override void OnTouchUp(TouchTargetEvent touchEvent) { base.OnTouchUp(touchEvent); int id = touchEvent.Touch.Id; // Depending on state, the touch will be in some of these dictionaries. // we don't need to track their state after this point for the given id // so just call remove since remove doesn't throw exceptions for items not the collection. thumbCapturedTouchesList.Remove(id); capturedCollectionLookup.Remove(id); // If there aren't any touches on the thumb stop manipulating. if (thumbCapturedTouchesList.Count == 0 && captureTouchesHitTestDetails.Count != 0) { if (manipulationProcessor != null) { // No more touches manipulationProcessor.ProcessManipulators(stopwatch.Elapsed100Nanoseconds(), null); } // The thumb is no longer captured so check to see what the selected part should be. if (GetFrontOfTrackQueue() == -1) selectedPart = ScrollBarPart.None; else selectedPart = ScrollBarPart.Track; } distanceOffset.Remove(id); captureTouchesHitTestDetails.Remove(id); }
/// <summary> /// Parameterized internal class constructor. /// </summary> /// <param name="touch"> /// An event that has occured for a Surface Touch.</param> /// <param name="model"> /// Interface for upating a state machine.</param> internal HitTestResult(TouchTargetEvent touch, IInputElementStateMachine model) { this.touch = touch; this.stateMachine = model; }
/// <summary> /// A contact has entered the element. /// </summary> /// <param name="touchEvent">The contact that entered.</param> protected override void OnTouchEnter(TouchTargetEvent touchEvent) { // Suppress OnContactEnter. }
/// <summary> /// Handles the <strong>TouchUp</strong> event. /// </summary> /// <param name="touchEvent">The container for the touch that the event is about.</param> protected override void OnTouchUp(TouchTargetEvent touchEvent) { base.OnTouchUp(touchEvent); scrollAdapter.ProcessTouchUp(touchEvent); }
//==========================================================// /// <summary> /// Handles contact changed events from the UIController. /// </summary> /// <param name="touchEvent">Event data.</param> protected override void OnTouchMoved(TouchTargetEvent touchEvent) { // Transform the contact into the screen coordinate system. Vector2 temp = Vector2.Transform(new Vector2(touchEvent.Touch.X, touchEvent.Touch.Y), Transform); // Remove manipulator if the Id already exists in the list. Can't update Manipulator2D // in-place as X and Y are read-only. // Using an anonymous predicate delegate to locate matching ManipulatorIds. currentManipulators.RemoveAll(delegate(Manipulator2D m) { return m.Id == touchEvent.Touch.Id; }); // Add it to the currentManipulators list with updated values. currentManipulators.Add(new Manipulator2D(touchEvent.Touch.Id, temp.X, temp.Y)); }
/// <summary> /// Called when a touch that is routed to this state machine goes down. /// </summary> /// <param name="touchEvent">The container object for the touch that is down.</param> protected virtual void OnTouchDown(TouchTargetEvent touchEvent) { if (touchEvent.Touch == null) throw SurfaceCoreFrameworkExceptions.ArgumentNullException("touch"); EventHandler<StateMachineTouchEventArgs> temp = TouchDown; if (temp != null) { temp(this, new StateMachineTouchEventArgs(touchEvent.Touch, this)); } }
/// <summary> /// Handles the TouchDown event. /// </summary> /// <param name="touchEvent"></param> public void ProcessTouchDown(TouchTargetEvent touchEvent) { // Stop inertia if it is occuring. if (processInertia) { StopFlick(); } // Reset the running actual to the current value. if (touchDownTouchInformation.Count == 0) { runningActualValueY = ConvertFromVerticalValueToControlSpace(verticalScrollBarStateMachine.Value); runningActualValueX = ConvertFromHorizontalValueToControlSpace(horizontalScrollBarStateMachine.Value); } // There was a touch hit tested to this so added it to the manipulation processor list. touchDownTouchInformation.Add(touchEvent.Touch.Id, touchEvent); // There was a touch hit tested to this so added it to the manipulation processor list. currentTouchInformation.Add(touchEvent.Touch.Id, touchEvent); }
/// <summary> /// Called when a touch that is routed to this state machine enters the state machine. /// </summary> /// <param name="touchEvent">The container for the touch that entered this state /// machine.</param> protected virtual void OnTouchEnter(TouchTargetEvent touchEvent) { if (touchEvent.Touch == null) throw SurfaceCoreFrameworkExceptions.ArgumentNullException("touch"); bool isTouchOverAlready = false; if (touchesOver.EditableTouchCollection.Contains(touchEvent.Touch.Id)) { isTouchOverAlready = true; this.touchesOver.EditableTouchCollection.Remove(touchEvent.Touch.Id); } this.touchesOver.EditableTouchCollection.Add(touchEvent.Touch); if (isTouchOverAlready) { // We already have the touch over the element, no event to raise. return; } EventHandler<StateMachineTouchEventArgs> temp = TouchEnter; if (temp != null) { temp(this, new StateMachineTouchEventArgs(touchEvent.Touch, this)); } }
/// <summary> /// Handles the TouchMoved event. /// </summary> /// <param name="touchEvent"></param> public void ProcessTouchMoved(TouchTargetEvent touchEvent) { // For each touch which changed update the item in the manipulation processor list. if (!currentTouchInformation.ContainsKey(touchEvent.Touch.Id)) { return; } ScrollViewerHitTestDetails hitTestDetails = touchEvent.HitTestDetails as ScrollViewerHitTestDetails; if (hitTestDetails == null) { return; } // Change the value for this touch. currentTouchInformation[touchEvent.Touch.Id] = touchEvent; float averageX, averageY; float actualValueX = 0, constrainedValueX = 0; float actualValueY = 0, constrainedValueY = 0; AverageTouchPosition(touchEvent, hitTestDetails, out averageX, out averageY); // Put the new position in the down so that we can use it to calculate change next time. touchDownTouchInformation[touchEvent.Touch.Id] = touchEvent; // Transform the value in to start position space and add the change for X actualValueX = averageX + ConvertFromHorizontalValueToControlSpace(horizontalScrollBarStateMachine.Value); // Constrain X constrainedValueX = FlickUtilities.Clamp(actualValueX, 0, 1 - HorizontalViewportSize); // Transform the value into start position space and add the change for Y actualValueY = averageY + ConvertFromVerticalValueToControlSpace(verticalScrollBarStateMachine.Value); // Constrain Y constrainedValueY = FlickUtilities.Clamp(actualValueY, 0, 1 - VerticalViewportSize); // Determine if the viewport start position is outside of the 0 to 1 range. float constrainedRunningY = FlickUtilities.Clamp(runningActualValueY, 0, 1 - VerticalViewportSize); float constrainedRunningX = FlickUtilities.Clamp(runningActualValueX, 0, 1 - HorizontalViewportSize); if ((Orientation & Orientation.Horizontal) != 0) { // Deal with Elasticity behavior for horizontal if (runningActualValueX == constrainedRunningX && actualValueX == constrainedValueX) { ClampScrollBarValueX(actualValueX, constrainedValueX); } else { SetElasticScrollBarValueX(averageX); } } if ((Orientation & Orientation.Vertical) != 0) { // Deal with Elasticity behavor for vertical if (runningActualValueY == constrainedRunningY && actualValueY == constrainedValueY) { ClampScrollBarValueY(actualValueY, constrainedValueY); } else { SetElasticScrollBarValueY(averageY); } } // Use this touch event to update the current manipulators. UpdateCurrentManipulators(touchEvent, hitTestDetails); }
/// <summary> /// Called when a touch that is routed to this state machine leaves the state machine. /// </summary> /// <param name="touchEvent">The container object for the departed touch.</param> protected virtual void OnTouchLeave(TouchTargetEvent touchEvent) { if (touchEvent.Touch == null) throw SurfaceCoreFrameworkExceptions.ArgumentNullException("touch"); if (touchesOver.EditableTouchCollection.Contains(touchEvent.Touch.Id)) this.touchesOver.EditableTouchCollection.Remove(touchEvent.Touch.Id); EventHandler<StateMachineTouchEventArgs> temp = TouchLeave; if (temp != null) { temp(this, new StateMachineTouchEventArgs(touchEvent.Touch, this)); } }
/// <summary> /// Updates manipulators to reflect the touch change. /// </summary> /// <param name="touchEvent">The new TouchTargetEvent</param> /// <param name="details">The contacEvent.HitTestDetails as ScrollViewerHitTestDetails</param> private void UpdateCurrentManipulators(TouchTargetEvent touchEvent, ScrollViewerHitTestDetails details) { // Try to find the changed touch in the manipulators list. bool foundManipulator = false; for (int i = 0; i < manipulations.Count; i++) { Manipulator2D manipulator = manipulations[i]; if (manipulator.Id == touchEvent.Touch.Id) { manipulations.Remove(manipulator); Manipulator2D manipulatorToAdd = new Manipulator2D(touchEvent.Touch.Id, ConvertFromHorizontalValueToScreenSpace(details.HorizontalPosition), ConvertFromVerticalValueToScreenSpace(details.VerticalPosition)); // Performance: It doesn't matter where we insert, but if all the touches are being updated, // then putting the most recent change at the end will mean that there is one less touch // to go through the next time this loop is executed. if (manipulations.Count == 0) { manipulations.Add(manipulatorToAdd); } else { manipulations.Insert(manipulations.Count - 1, manipulatorToAdd); } foundManipulator = true; break; } } // The manipulator isn't in the list so add it. if (!foundManipulator) { manipulations.Add(new Manipulator2D(touchEvent.Touch.Id, ConvertFromHorizontalValueToScreenSpace(details.HorizontalPosition), ConvertFromVerticalValueToScreenSpace(details.VerticalPosition))); } }
/// <summary> /// Handles <strong>TouchDown</strong> events. /// </summary> /// <param name="touchEvent">The list Box item touch that was added.</param> protected override void OnTouchDown(TouchTargetEvent touchEvent) { base.OnTouchDown(touchEvent); ListBoxMode = ListBoxMode.Selection; // Capture the touch to the ListBox Controller.Capture(touchEvent.Touch, this); // Get the item based on the touch details. ListBoxStateMachineItem item = GetItemHit(touchEvent.HitTestDetails as ListBoxHitTestDetails); // The item could be null if there are fewer items whose sizes sum to less than the size of the ListBox. if (item == null) return; // Put the touch on the listbox item. Internal hit test to figure out which item it's over. capturedItemTouchIds.Add(touchEvent.Touch.Id, item); // Have the item process TouchDown. item.ProcessTouchDown(touchEvent.Touch.Id); // The item should change based on having a touch over it? // Store the position. touchTargetEventTouchIds.Add(touchEvent.Touch.Id, touchEvent); }