示例#1
0
        /// <summary>
        /// Handles the <strong>ContactDown</strong> event.
        /// </summary>
        /// <param name="contactEvent">The container for the contact that the event is about.</param>
        protected override void OnContactDown(ContactTargetEvent contactEvent)
        {
            base.OnContactDown(contactEvent);

            // Did the contact hit the thumb or the track.
            ScrollBarPart partHit = GetScrollBarPartHit(contactEvent.HitTestDetails as ScrollBarHitTestDetails);

            // The contact went down on the ScrollBar so capture it.
            Controller.Capture(contactEvent.Contact, this);

            ScrollBarHitTestDetails details = contactEvent.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("contactEvent.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 contact to the thumb list so that it can be used for averaging.
                    thumbCapturedContactsList.Add(contactEvent.Contact.Id);

                    // Tie this contact id to the Thumb.
                    capturedCollectionLookup.Add(contactEvent.Contact.Id, ScrollBarPart.Thumb);

                    // We need to be able to look up the hit test details later so save that off.
                    captureContactsHitTestDetails.Add(contactEvent.Contact.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(contactEvent.Contact.Id, details.Position - (Value * (1 - ViewportSize)));

                    break;

                // The Track was hit.
                case ScrollBarPart.Track:

                    // Place the contact at the end of the track queue.
                    trackQueue.Enqueue(contactEvent.Contact.Id);

                    // Tie this contact to the Track.
                    capturedCollectionLookup.Add(contactEvent.Contact.Id, ScrollBarPart.Track);

                    // We need to be able to look up the hit test details later so save that off.
                    captureContactsHitTestDetails.Add(contactEvent.Contact.Id, details);

                    // The thumb has contacts captured so don't proceed.
                    if (thumbCapturedContactsList.Count != 0)
                        return;

                    int id = GetFrontOfTrackQueue();

                    // If the id isn't the same as contact id which went down don't proceed.
                    if (id != contactEvent.Contact.Id)
                        return;

                    selectedPart = ScrollBarPart.Track;

                    // The contact hit before the thumb.
                    if (details.Position < ThumbStartPosition)
                    {
                        if (isReversed)
                        {
                            PageForward();
                        }
                        else
                        {
                            PageBack();
                        }
                    }
                    else // The contact hit after the thumb
                    {
                        if (isReversed)
                        {
                            PageBack();
                        }
                        else
                        {
                            PageForward();
                        }
                    }
                    break;
                default:
                    break;
            }
        }
示例#2
0
        /// <summary>
        /// Handles the <strong>ContactUp</strong> event.
        /// </summary>
        /// <param name="contactEvent">The container for the contact that the event is about.</param>
        protected override void OnContactUp(ContactTargetEvent contactEvent)
        {
            base.OnContactUp(contactEvent);

            int id = contactEvent.Contact.Id;

            // Depending on state, the contact 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.
            thumbCapturedContactsList.Remove(id);
            capturedCollectionLookup.Remove(id);

            // If there aren't any contacts on the thumb stop manipulating.
            if (thumbCapturedContactsList.Count == 0 && captureContactsHitTestDetails.Count != 0)
            {
                if (manipulationProcessor != null)
                {
                    ScrollBarHitTestDetails hitTestDetails = captureContactsHitTestDetails[id] as ScrollBarHitTestDetails;

                    float offset = 0;

                    if (distanceOffset.ContainsKey(id))
                    {
                        offset = distanceOffset[id];
                    }

                    // The Manipulations should all run in screen space.
                    manipulationProcessor.ProcessManipulators(stopwatch.ElapsedTicks, new List<Manipulator>(), new List<Manipulator> { new Manipulator(id, ToScreenSpace(hitTestDetails.Position - offset), 0) });
                }

                // 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);
            captureContactsHitTestDetails.Remove(id);
        }
示例#3
0
        /// <summary>
        /// Handles <strong>ContactDown</strong> events.
        /// </summary>
        /// <param name="contactEvent">The list Box item contact that was added.</param>
        protected override void OnContactDown(ContactTargetEvent contactEvent)
        {
            base.OnContactDown(contactEvent);

            ListBoxMode = ListBoxMode.Selection;

            // Capture the contact to the ListBox
            Controller.Capture(contactEvent.Contact, this);

            // Get the item based on the contact details.
            ListBoxStateMachineItem item = GetItemHit(contactEvent.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 contact on the listbox item.  Internal hit test to figure out which item it's over.
            capturedItemContactIds.Add(contactEvent.Contact.Id, item);

            // Have the item process ContactDown.
            item.ProcessContactDown(contactEvent.Contact.Id);

            // The item should change based on having a contact over it?
            // Store the position.
            contactTargetEventContactIds.Add(contactEvent.Contact.Id, contactEvent);
        }
示例#4
0
        /// <summary>
        /// Handles the ContactChanged event.
        /// </summary>
        /// <param name="contactEvent"></param>
        public void ProcessContactChanged(ContactTargetEvent contactEvent)
        {
            // For each contact which changed update the item in the manipulation processor list.
            if (!currentContactInformation.ContainsKey(contactEvent.Contact.Id))
            {
                return;
            }

            ScrollViewerHitTestDetails hitTestDetails = contactEvent.HitTestDetails as ScrollViewerHitTestDetails;
            if (hitTestDetails == null)
            {
                return;
            }

            // Change the value for this contact.
            currentContactInformation[contactEvent.Contact.Id] = contactEvent;

            float averageX, averageY;
            float actualValueX = 0, constrainedValueX = 0;
            float actualValueY = 0, constrainedValueY = 0;

            AverageContactPosition(contactEvent, hitTestDetails, out averageX, out averageY);

            // Put the new position in the down so that we can use it to calculate change next time.
            contactDownContactInformation[contactEvent.Contact.Id] = contactEvent;

            // 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 contact event to update the current manipulators.
            UpdateCurrentManipulators(contactEvent, hitTestDetails);
        }
示例#5
0
        /// <summary>
        /// Calls <strong><see cref="M:CoreInteractionFramework.ButtonStateMachine.OnClick" /></strong> 
        /// if the contact is captured over the button and there are no more captured contacts.
        /// </summary>
        /// <param name="contactEvent">The contact that was removed.</param>
        protected override void OnContactUp(ContactTargetEvent contactEvent)
        {
            if (ClickMode == ClickMode.Release
                && ContactsCaptured.Contains(contactEvent.Contact.Id)
                && ContactsCaptured.Count == 1)
            {
                if (Controller.DoesHitTestMatchCapture(contactEvent.Contact))
                {
                    releaseModeContactUp = true;
                }
            }

            base.OnContactUp(contactEvent);

            switch (ClickMode)
            {
                case ClickMode.Release:
                case ClickMode.Press:
                    foreach (Contact capturedContact in ContactsCaptured)
                    {
                        if (Controller.DoesHitTestMatchCapture(capturedContact))
                        {
                            isPressed = true;
                            return;
                        }
                    }
                    isPressed = false;
                    break;

                case ClickMode.Hover:
                    if (this.ContactsOver.Count == 0)
                        isPressed = false;
                    break;
                default:
                    break;
            }
        }
示例#6
0
        /// <summary>
        /// Updates the position of the contact information in contactTargetEventContactIds
        /// </summary>
        /// <param name="contactEvent"></param>
        private void UpdateContactPosition(ContactTargetEvent contactEvent)
        {
            // Based on the down position in contactTargetEventContactIds track how much this item has changed
            // and place it in contactChangeDeltaContactIds
            int contactId = contactEvent.Contact.Id;

            if (!contactTargetEventContactIds.ContainsKey(contactId))
            {
                return;
            }

            if (contactChangeDeltaContactIds.ContainsKey(contactId))
            {
                ListBoxHitTestDetails originalDetails = (ListBoxHitTestDetails)contactTargetEventContactIds[contactId].HitTestDetails;
                ListBoxHitTestDetails currentDetails = contactEvent.HitTestDetails as ListBoxHitTestDetails;

                if (currentDetails == null)
                {
                    return;
                }

                float original = 0f, current = 0f;

                if (Orientation == Orientation.Horizontal)
                {
                    current = currentDetails.HorizontalPosition;
                    original = originalDetails.HorizontalPosition;
                }
                else
                {
                    current = currentDetails.VerticalPosition;
                    original = originalDetails.VerticalPosition;
                }

                // Get the total distance this contact has moved since it went down.
                contactChangeDeltaContactIds[contactId] = current - original;
            }
            else
            {
                contactChangeDeltaContactIds.Add(contactId, 0f);
            }
        }
示例#7
0
        /// <summary>
        /// Handles ContactRemoved events from the ContactTarget
        /// </summary>
        private void OnContactRemoved(object sender, ContactEventArgs e)
        {
            ContactTargetEvent cte = new ContactTargetEvent(ContactEventType.Removed, e.Contact);

            lock (swapLock)
            {
                this.orderedContactEventsBackbuffer.Enqueue(cte);

                if (this.orderedContactEventsBackbuffer.Count > MaximumQueueSize)
                {
                    throw SurfaceCoreFrameworkExceptions.MaximumQueueSizeReached(MaximumQueueSize);
                }
            }
        }
示例#8
0
 /// <summary>
 /// Calls <strong><see cref="M:CoreInteractionFramework.ButtonStateMachine.OnClick" /></strong> 
 /// if there are no contacts over and 
 /// <strong><see cref="P:CoreInteractionFramework.ButtonStateMachine.ClickMode" /></strong> is <strong>Hover</strong>.
 /// </summary>
 /// <param name="contactEvent">The contact that entered.</param>
 protected override void OnContactEnter(ContactTargetEvent contactEvent)
 {
     switch (ClickMode)
     {
         case ClickMode.Hover:
             if (this.ContactsOver.Count == 0)
             {
                 isPressed = true;
                 OnClick();
             }
             break;
         case ClickMode.Press:
         case ClickMode.Release:
         default:
             break;
     }
     base.OnContactEnter(contactEvent);
 }
示例#9
0
        private void HitTestFail(HitTestResult hitTestResult)
        {
            IInputElementStateMachine stateMachine;

            // Check to see if this contact is captured to an IInputElementStateMachine.
            if (capturedContacts.TryGetValue(hitTestResult.Contact.Id, out stateMachine))
            {
                if (hitTestResult.ContactTargetEvent.EventType == ContactEventType.Removed)
                {
                    // Send the up notification to the old statemachine.
                    packagedContacts.Add(hitTestResult.ContactTargetEvent, stateMachine);

                    // Send leave notification to the old statemachine.
                    ContactTargetEvent leaveEvent = new ContactTargetEvent(ContactEventType.Leave, hitTestResult.Contact);
                    packagedContacts.Add(leaveEvent, stateMachine);
                }
                else
                {
                    // Send the leave notification to the old statemachine.
                    packagedContacts.Add(hitTestResult.ContactTargetEvent, stateMachine);
                }

                // If this contact was over it shouldn't be any longer.
                if (contactsOver.ContainsKey(hitTestResult.Contact.Id))
                {
                    contactsOver.Remove(hitTestResult.Contact.Id);
                }

            }
            else
            {
                // Is this contact over an IInputElementStateMachine currently?
                if (contactsOver.TryGetValue(hitTestResult.Contact.Id, out stateMachine))
                {
                    // The contact just moved off the edge of the IInputElementStateMachine.
                    if (hitTestResult.ContactTargetEvent.EventType == ContactEventType.Changed)
                    {
                        hitTestResult.ContactTargetEvent.EventType = ContactEventType.Leave;
                    }

                    // Send the notification to the old statemachine.
                    packagedContacts.Add(hitTestResult.ContactTargetEvent, stateMachine);

                    contactsOver.Remove(hitTestResult.Contact.Id);
                }
            }

            // The contact isn't captured, isn't in the contacts over
            // and it didn't hit anything so there is no where to route it.
        }
示例#10
0
        private void HitTestSuccess(HitTestResult hitTestResult)
        {
            if (hitTestResult.StateMachine.Controller != this)
            {
                throw SurfaceCoreFrameworkExceptions.ControllerSetToADifferentControllerException(hitTestResult.StateMachine);
            }

            // Check if the ContactId is in the contactsOver collection.
            IInputElementStateMachine overStateMachine;
            if (contactsOver.TryGetValue(hitTestResult.Contact.Id, out overStateMachine))
            {
                // Then check if the hitTestResult is over the sane statemachine
                if (hitTestResult.StateMachine == overStateMachine)
                {
                    // Just because the contactOver 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 (capturedContacts.TryGetValue(hitTestResult.Contact.Id, out capturedStateMachine))
                    {
                        if (hitTestResult.ContactTargetEvent.EventType == ContactEventType.Removed)
                        {
                            // Send the up notification to the old statemachine.
                            packagedContacts.Add(hitTestResult.ContactTargetEvent, capturedStateMachine);

                            // Send leave notification to the old statemachine.
                            ContactTargetEvent leaveEvent = new ContactTargetEvent(ContactEventType.Leave,
                                                                                   hitTestResult.Contact);
                            packagedContacts.Add(leaveEvent, capturedStateMachine);
                        }
                        else
                        {
                            packagedContacts.Add(hitTestResult.ContactTargetEvent, capturedStateMachine);
                        }

                    }
                    else
                    {
                        // Contact is not currently captured.
                        if (hitTestResult.ContactTargetEvent.EventType == ContactEventType.Removed)
                        {
                            // Send the up notification to the old statemachine.
                            packagedContacts.Add(hitTestResult.ContactTargetEvent, hitTestResult.StateMachine);

                            // Send leave notification to the old statemachine.
                            ContactTargetEvent leaveEvent = new ContactTargetEvent(ContactEventType.Leave,
                                                                                   hitTestResult.Contact);

                            packagedContacts.Add(leaveEvent, hitTestResult.StateMachine);
                        }
                        else
                        {
                            packagedContacts.Add(hitTestResult.ContactTargetEvent, hitTestResult.StateMachine);
                        }
                    }

                    // No calls to RoutePackagedContacts() and packagedContacts.Clear()
                    // When hitTestResult.StateMachine and overStateMachine are the same.

                }
                else
                {
                    // It's over a different statemachine.

                    // Remove the old IInputElementStateMachine from the contactsOver collection.
                    contactsOver.Remove(hitTestResult.Contact.Id);

                    // Add the new IInputElementStateMachine to the contactsOver collection
                    contactsOver.Add(hitTestResult.Contact.Id, hitTestResult.StateMachine);

                    IInputElementStateMachine capturedStateMachine;
                    if (capturedContacts.TryGetValue(hitTestResult.Contact.Id, out capturedStateMachine))
                    {
                        // Contact is captured, but over a different statemachine.
                        // If the contact is captured then don't send enter leave events.

                        // Route this event to the capturedStateMachine.
                        packagedContacts.Add(hitTestResult.ContactTargetEvent, capturedStateMachine);
                    }
                    else
                    {
                        // Contact is not captured over a new statemachine.

                        // It's not over the same statemachine, so we need to add a leave ContactTargetEvent to tell
                        // the statemachine its leaving.
                        ContactTargetEvent leaveEvent = new ContactTargetEvent(ContactEventType.Leave,
                                                                               hitTestResult.Contact);

                        // We need to add the leave event or it will not get routed.
                        packagedContacts.Add(leaveEvent, overStateMachine);

                        // Then change the EventType to Enter so that the new statemachine
                        // will know a Contact just entered.
                        hitTestResult.ContactTargetEvent.EventType = ContactEventType.Enter;
                        packagedContacts.Add(hitTestResult.ContactTargetEvent, hitTestResult.StateMachine);

                    }

                    // Route contacts and remove the added ones anytime a contact Enter, Add, Remove or Leaves.
                    RoutePackagedContacts();
                    packagedContacts.Clear();
                }
            }
            else
            {
                // Not in contactsOver.

                // This contact is just coming over a statemachine either change or add.

                // Check to see if this contact is captured to an IInputElementStateMachine.
                IInputElementStateMachine capturedStateMachine = null;
                if (capturedContacts.TryGetValue(hitTestResult.Contact.Id, out capturedStateMachine))
                {
                    // ContactsOver should reflect which element this contact is over, not which it's captured too.
                    contactsOver.Add(hitTestResult.Contact.Id, hitTestResult.StateMachine);

                    // We should send this event to the element that captured it.
                    packagedContacts.Add(hitTestResult.ContactTargetEvent, capturedStateMachine);
                }
                else
                {
                    // Not captured.

                    // We want to send an Enter event instead of a changed.
                    if (hitTestResult.ContactTargetEvent.EventType == ContactEventType.Changed)
                    {
                        hitTestResult.ContactTargetEvent.EventType = ContactEventType.Enter;
                    }

                    if (hitTestResult.ContactTargetEvent.EventType == ContactEventType.Added)
                    {
                        ContactTargetEvent enterEvent = new ContactTargetEvent(ContactEventType.Enter, hitTestResult.Contact);
                        packagedContacts.Add(enterEvent, hitTestResult.StateMachine);
                    }

                    // This contact is now over this IInputElementStateMachine.
                    switch (hitTestResult.ContactTargetEvent.EventType)
                    {
                        case ContactEventType.Enter:
                        case ContactEventType.Added:
                            contactsOver.Add(hitTestResult.Contact.Id, hitTestResult.StateMachine);
                            break;
                        case ContactEventType.Removed:
                        case ContactEventType.Leave:
                            Debug.Fail("If we get an removed or leave we missed adding it to an IInputElementStateMachine somewhere.");
                            break;
                    }

                    packagedContacts.Add(hitTestResult.ContactTargetEvent, hitTestResult.StateMachine);
                }
                // Route contacts and remove the added ones anytime a contact Enter, Add, Remove or Leaves.
                RoutePackagedContacts();
                packagedContacts.Clear();

            }
        }
示例#11
0
        /// <summary>
        /// Averages the position of the contactEvent.HitTestDetails position based on the number of contacts.
        /// </summary>
        /// <param name="contactEvent">The new ContactTargetEvent</param>
        /// <param name="hitTestDetails">The contacEvent.HitTestDetails as ScrollViewerHitTestDetails</param>
        /// <param name="averageX"></param>
        /// <param name="averageY"></param>
        private void AverageContactPosition(ContactTargetEvent contactEvent,
                                            ScrollViewerHitTestDetails hitTestDetails,
                                            out float averageX, out float averageY)
        {
            // Get the down hitTestDetails for this contact.
            ScrollViewerHitTestDetails downDetails =
                contactDownContactInformation[contactEvent.Contact.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 contacts on the Surface.
            averageX /= contactDownContactInformation.Count;
            averageY /= contactDownContactInformation.Count;
        }
示例#12
0
        /// <summary>
        /// Handles the ContactUp event.
        /// </summary>
        /// <param name="contactEvent"></param>
        public void ProcessContactUp(ContactTargetEvent contactEvent)
        {
            if (!currentContactInformation.ContainsKey(contactEvent.Contact.Id)) { return; }

            Manipulator? removed = null;

            currentContactInformation.Remove(contactEvent.Contact.Id);
            contactDownContactInformation.Remove(contactEvent.Contact.Id);

            // Find the manipulator that is being removed.
            for (int i = 0; i < manipulations.Count; i++)
            {
                Manipulator manipulator = manipulations[i];

                if (manipulator.ManipulatorId == contactEvent.Contact.Id)
                {
                    manipulations.Remove(manipulator);
                    removed = manipulator;
                    break;
                }
            }

            if (removed != null)
            {
                removedManipulations.Add(removed.Value);
            }

            if (contactDownContactInformation.Count == 0)
            {
                runningActualValueY = ConvertFromVerticalValueToControlSpace(verticalScrollBarStateMachine.Value);
                runningActualValueX = ConvertFromHorizontalValueToControlSpace(horizontalScrollBarStateMachine.Value);

                verticalViewportStartPosition = runningActualValueY;
                horizontalViewportStartPosition = runningActualValueX;

                OnViewportChanged();
            }
        }
示例#13
0
        /// <summary>
        /// Handles the ContactDown event.
        /// </summary>
        /// <param name="contactEvent"></param>
        public void ProcessContactDown(ContactTargetEvent contactEvent)
        {
            // Stop inertia if it is occuring.
            if (processInertia)
            {
                StopFlick();
            }

            // Reset the running actual to the current value.
            if (contactDownContactInformation.Count == 0)
            {
                runningActualValueY = ConvertFromVerticalValueToControlSpace(verticalScrollBarStateMachine.Value);
                runningActualValueX = ConvertFromHorizontalValueToControlSpace(horizontalScrollBarStateMachine.Value);
            }

            // There was a contact hit tested to this so added it to the manipulation processor list.
            contactDownContactInformation.Add(contactEvent.Contact.Id, contactEvent);

            // There was a contact hit tested to this so added it to the manipulation processor list.
            currentContactInformation.Add(contactEvent.Contact.Id, contactEvent);
        }
示例#14
0
        /// <summary>
        /// Handles the <strong><see cref="E:CoreInteractionFramework.UIElementStateMachine.ContactChanged" /></strong> event.
        /// </summary>
        /// <param name="contactEvent">The contact that changed.</param>
        protected override void OnContactChanged(ContactTargetEvent contactEvent)
        {
            base.OnContactChanged(contactEvent);

            // If the contact is captured to this control then check to see if it or
            // any other contact hit tested to the control.
            if (Controller.GetCapturingElement(contactEvent.Contact) == this)
            {
                foreach (Contact capturedContact in ContactsCaptured)
                {
                    if (Controller.DoesHitTestMatchCapture(capturedContact))
                    {
                        isPressed = true;
                        return;
                    }
                }
                isPressed = false;
            }
        }
示例#15
0
        /// <summary>
        /// Called when a contact that is routed to this state machine goes down.
        /// </summary>
        /// <param name="contactEvent">The container object for the contact that is down.</param>
        protected virtual void OnContactDown(ContactTargetEvent contactEvent)
        {
            if (contactEvent.Contact == null)
                throw SurfaceCoreFrameworkExceptions.ArgumentNullException("contact");

            EventHandler<StateMachineContactEventArgs> temp = ContactDown;

            if (temp != null)
            {
                temp(this, new StateMachineContactEventArgs(contactEvent.Contact, this));
            }
        }
示例#16
0
        /// <summary>
        /// Changes the state of the button based on the <strong><see cref="P:CoreInteractionFramework.ButtonStateMachine.ClickMode" /></strong>
        /// property.
        /// </summary>
        /// <param name="contactEvent">The contact that hit the button.</param>
        protected override void OnContactDown(ContactTargetEvent contactEvent)
        {
            this.IsPressed = true;

            switch (ClickMode)
            {
                case ClickMode.Press:
                    if (this.ContactsCaptured.Count == 0)
                        OnClick();
                    this.Controller.Capture(contactEvent.Contact, this);
                    break;

                case ClickMode.Release:
                    this.Controller.Capture(contactEvent.Contact, this);
                    break;

                case ClickMode.Hover:
                    if (this.ContactsOver.Count == 0)
                    {
                        OnClick();
                    }
                    break;
                default:
                    break;
            }

            base.OnContactDown(contactEvent);
        }
示例#17
0
        /// <summary>
        /// Called when a contact that is routed to this state machine enters the state machine.
        /// </summary>
        /// <param name="contactEvent">The container for the contact that entered this state 
        /// machine.</param>
        protected virtual void OnContactEnter(ContactTargetEvent contactEvent)
        {
            if (contactEvent.Contact == null)
                throw SurfaceCoreFrameworkExceptions.ArgumentNullException("contact");

            if (contactsOver.CachedContactCollection.Contains(contactEvent.Contact.Id))
                throw SurfaceCoreFrameworkExceptions.ContactIsAlreadyInCollection(contactEvent.Contact, contactsOver.CachedContactCollection);

            Debug.Assert(!contactsOver.EditableContactCollection.Contains(contactEvent.Contact.Id), "Contact was not in the CachedContactCollection, but is in the EditableContactCollection.");

            this.contactsOver.EditableContactCollection.Add(contactEvent.Contact);

            EventHandler<StateMachineContactEventArgs> temp = ContactEnter;

            if (temp != null)
            {
                temp(this, new StateMachineContactEventArgs(contactEvent.Contact, this));
            }
        }
示例#18
0
        /// <summary>
        /// Called when the Contact has left the button.
        /// </summary>
        /// <param name="contactEvent">The contact that departed.</param>
        protected override void OnContactLeave(ContactTargetEvent contactEvent)
        {
            base.OnContactLeave(contactEvent);

            switch (ClickMode)
            {
                case ClickMode.Hover:
                    if (this.ContactsOver.Count == 0)
                        isPressed = false;
                    break;
                case ClickMode.Press:
                case ClickMode.Release:
                default:
                    break;
            }
        }
示例#19
0
        /// <summary>
        /// Called when a contact that is routed to this state machine leaves the state machine.
        /// </summary>
        /// <param name="contactEvent">The container object for the departed contact.</param>
        protected virtual void OnContactLeave(ContactTargetEvent contactEvent)
        {
            if (contactEvent.Contact == null)
                throw SurfaceCoreFrameworkExceptions.ArgumentNullException("contact");

            if (contactsOver.EditableContactCollection.Contains(contactEvent.Contact.Id))
                this.contactsOver.EditableContactCollection.Remove(contactEvent.Contact.Id);

            EventHandler<StateMachineContactEventArgs> temp = ContactLeave;

            if (temp != null)
            {
                temp(this, new StateMachineContactEventArgs(contactEvent.Contact, this));
            }
        }
示例#20
0
 /// <summary>
 /// Parameterized internal class constructor.
 /// </summary>
 /// <param name="contact">
 /// An event that has occured for a Surface Contact.</param>
 /// <param name="model">
 /// Interface for upating a state machine.</param>
 internal HitTestResult(ContactTargetEvent contact, IInputElementStateMachine model)
 {
     this.contact = contact;
     this.stateMachine = model;
 }
示例#21
0
        /// <summary>
        /// Called when a contact that is routed to this state machine is removed.
        /// </summary>
        /// <param name="contactEvent">The container for the removed contact.</param>
        protected virtual void OnContactUp(ContactTargetEvent contactEvent)
        {
            if (contactEvent.Contact == null)
                throw SurfaceCoreFrameworkExceptions.ArgumentNullException("contact");

            if (!contactsOver.CachedContactCollection.Contains(contactEvent.Contact.Id) && !contactsCaptured.CachedContactCollection.Contains(contactEvent.Contact.Id))
                throw SurfaceCoreFrameworkExceptions.ContactIsNotInCollection(contactEvent.Contact, contactsOver.CachedContactCollection);

            Debug.Assert(contactsOver.EditableContactCollection.Contains(contactEvent.Contact.Id) || contactsCaptured.EditableContactCollection.Contains(contactEvent.Contact.Id), "Contact was not in the CachedContactCollection, but is in the EditableContactCollection.");

            if (contactsOver.EditableContactCollection.Contains(contactEvent.Contact.Id))
                this.contactsOver.EditableContactCollection.Remove(contactEvent.Contact.Id);

            EventHandler<StateMachineContactEventArgs> temp = ContactUp;

            if (temp != null)
            {
                temp(this, new StateMachineContactEventArgs(contactEvent.Contact, this));
            }

            if (contactsCaptured.CachedContactCollection.Contains(contactEvent.Contact.Id))
            {
                Controller.Release(contactEvent.Contact);
            }
        }
示例#22
0
        /// <summary>
        /// Handles <strong>ContactChanged</strong> events.
        /// </summary>
        /// <param name="contactEvent">The list box item contact that changed.</param>
        protected override void OnContactChanged(ContactTargetEvent contactEvent)
        {
            base.OnContactChanged(contactEvent);

            if (ListBoxMode == ListBoxMode.Selection)
            {
                // Update the contact position and track total change.
                UpdateContactPosition(contactEvent);

                // If the ListBox is in scroll mode then route this contact to the scrollAdapter.
                // If in selection mode check to see if the contact has moved 1/8"
                // and change to scrolling mode if it has.
                if (DidContactMovePastThreshold(contactEvent.Contact.Id))
                {
                    ListBoxMode = ListBoxMode.Scrolling;

                    // Uncapture contacts from items and send capture
                    // information to the ScrollViewer for every captured contacts.
                    foreach (KeyValuePair<int, ContactTargetEvent> downContact in contactTargetEventContactIds)
                    {
                        // Get the ListBoxItem this contact is "captured" to.
                        ListBoxStateMachineItem item = capturedItemContactIds[downContact.Value.Contact.Id];

                        // Set the pressed state to false for this item.
                        item.IsPressed = false;
                        item.ChangeToScrolling();
                        item.capturedContacts.Clear();

                        if (!scrollAdapterContacts.Contains(downContact.Key))
                        {
                            // Track which contact ids have been added to the scroll adapter.
                            scrollAdapterContacts.Add(downContact.Key);

                            // Process each contact as a contact down.
                            scrollAdapter.ProcessContactDown(downContact.Value);
                        }
                    }
                }
            }
            else
            {
                // If the ListBox is scrollling then pass information to the scrollAdapter.
                scrollAdapter.ProcessContactChanged(contactEvent);
            }
        }
示例#23
0
        /// <summary>
        /// Handles the <strong>ContactChanged</strong> event.
        /// </summary>
        /// <param name="contactEvent">The container for the contact that the event is about.</param>
        protected override void OnContactChanged(ContactTargetEvent contactEvent)
        {
            base.OnContactChanged(contactEvent);

            // Figure out if this contact is in the list or queue.
            if (capturedCollectionLookup.ContainsKey(contactEvent.Contact.Id))
            {
                ScrollBarPart part = capturedCollectionLookup[contactEvent.Contact.Id];

                // Update the hitTestDetails for this contact id.
                ScrollBarHitTestDetails details = contactEvent.HitTestDetails as ScrollBarHitTestDetails;
                if (details != null)
                {
                    captureContactsHitTestDetails[contactEvent.Contact.Id] = details;
                }

                // We only care about changes in the thumb.
                if (part == ScrollBarPart.Thumb)
                {
                    if (!captureContactsHitTestDetails.ContainsKey(contactEvent.Contact.Id))
                    {
                        Debug.Fail("A contact changed occured on the thumb, but the contact wasn't captured");
                    }

                    // Get the average position over the thumb.
                    float averagePoint = AverageCapturedContactsInThumbList();

                    // Update the value and thumb properties.  Convert into Value space.
                    UpdatedValueInValueSpace(averagePoint / (1 - viewportSize));
                }
            }
            isScrolling = true;
        }
示例#24
0
        /// <summary>
        /// Handles <strong>ContactUp</strong> events.
        /// </summary>
        /// <param name="contactEvent">The contact that is removed from the list box item.</param>
        protected override void OnContactUp(ContactTargetEvent contactEvent)
        {
            if (ContactsCaptured.Contains(contactEvent.Contact.Id))
            {
                // Remove the items from tracking.
                if (capturedItemContactIds.ContainsKey(contactEvent.Contact.Id))
                {
                    // Get the ListBoxItem this contact is "captured" to.
                    ListBoxStateMachineItem item = capturedItemContactIds[contactEvent.Contact.Id];

                    if (ListBoxMode == ListBoxMode.Scrolling)
                    {
                        scrollAdapter.ProcessContactUp(contactEvent);

                        // 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 contact up when the contact is captured
                        // as it will cause the item to be select/deselected.
                        // Also item's IsPressed state will be cleared if scrolling begins.
                        item.ProcessCapturedContactUp(contactEvent.Contact.Id);

                    }

                    // The contact is up so we don't need to track this item.
                    capturedItemContactIds.Remove(contactEvent.Contact.Id);
                    contactTargetEventContactIds.Remove(contactEvent.Contact.Id);
                    scrollAdapterContacts.Remove(contactEvent.Contact.Id);
                    contactChangeDeltaContactIds.Remove(contactEvent.Contact.Id);
                }

                // Release the contact.
                Controller.Release(contactEvent.Contact);

                if (ContactsCaptured.Count == 0)
                {
                    ListBoxMode = ListBoxMode.Selection;
                }
            }

            // Select the item if in selection mode
            // Release capture on the contact.
            base.OnContactUp(contactEvent);
        }
示例#25
0
        /// <summary>
        /// Updates manipulators to reflect the contact change.
        /// </summary>
        /// <param name="contactEvent">The new ContactTargetEvent</param>
        /// <param name="details">The contacEvent.HitTestDetails as ScrollViewerHitTestDetails</param>
        private void UpdateCurrentManipulators(ContactTargetEvent contactEvent, ScrollViewerHitTestDetails details)
        {
            // Try to find the changed contact in the manipulators list.
            bool foundManipulator = false;
            for (int i = 0; i < manipulations.Count; i++)
            {
                Manipulator manipulator = manipulations[i];

                if (manipulator.ManipulatorId == contactEvent.Contact.Id)
                {
                    manipulations.Remove(manipulator);

                    Manipulator manipulatorToAdd = new Manipulator(contactEvent.Contact.Id,
                                                                   ConvertFromHorizontalValueToScreenSpace(details.HorizontalPosition),
                                                                   ConvertFromVerticalValueToScreenSpace(details.VerticalPosition));

                    // Performance: It doesn't matter where we insert, but if all the contacts are being updated,
                    // then putting the most recent change at the end will mean that there is one less contact
                    // 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 Manipulator(contactEvent.Contact.Id,
                                                  ConvertFromHorizontalValueToScreenSpace(details.HorizontalPosition),
                                                  ConvertFromVerticalValueToScreenSpace(details.VerticalPosition)));
            }
        }