/// <summary>
        /// Called to capture input and manage events. All layers will get events, they must determine if they want
        /// to work based on the EventProcessingAllowed property of their event layer.
        /// </summary>
        /// <param name="time">The clock with info about this frame.</param>
        public void updateEvents(Clock clock)
        {
            //Process the whole update with the same focus layer
            EventLayer currentFocusLayer = focusLayer;

            pad1Hardware.Update();
            pad2Hardware.Update();
            pad3Hardware.Update();
            pad4Hardware.Update();
            mouse.capture();
            bool allowEventProcessing = true; //The first layer always gets all events

            //If there is a focus layer, process it first
            if (currentFocusLayer != null)
            {
                allowEventProcessing = processLayer(clock, allowEventProcessing, currentFocusLayer);
            }

            //Process all other layers skipping the focus layer
            foreach (var layer in eventLayers)
            {
                if (layer != currentFocusLayer)
                {
                    allowEventProcessing = processLayer(clock, allowEventProcessing, layer);
                }
            }
            mouse.postUpdate();
            touches.tick();
        }
 /// <summary>
 /// Clear the focus layer if the passed layer is currently the focus layer, otherwise does nothing.
 /// </summary>
 internal void clearFocusLayer(EventLayer layer)
 {
     if (focusLayer == layer)
     {
         focusLayer = null;
     }
 }
        private void computeZoom(EventLayer eventLayer, ref bool didGesture, Finger finger1, Finger finger2, ref Vector2 finger1Vec, ref Vector2 finger2Vec)
        {
            Vector2 finger1Pos           = new Vector2(finger1.NrmlX, finger1.NrmlY);
            Vector2 finger2Pos           = new Vector2(finger2.NrmlX, finger2.NrmlY);
            float   currentPinchDistance = (finger1Pos - finger2Pos).length2();

            Vector2 vectorSum = finger1Vec - finger2Vec;

            momentumDirection = 1.0f;
            zoomDelta         = vectorSum.length();
            momentum          = zoomDelta;
            deceleration      = momentum / decelerationTime;

            if (currentPinchDistance > lastPinchDistance)
            {
                zoomDelta         = -zoomDelta;
                momentumDirection = -1.0f;
            }
            didGesture        = true;
            lastPinchDistance = currentPinchDistance;

            if (!gestureStarted)
            {
                gestureStarted = true;
                if (GestureStarted != null)
                {
                    GestureStarted.Invoke(eventLayer, this);
                }
            }

            if (Zoom != null)
            {
                Zoom.Invoke(eventLayer, this);
            }
        }
        /// <summary>
        /// Process a layer.
        /// </summary>
        private static bool processLayer(Clock clock, bool allowEventProcessing, EventLayer layer)
        {
            //First try to update the layer with the current allowEventProcessing
            layer.update(allowEventProcessing, clock);

            //Modify allowEventProcessing as needed, if we have already set allowEventProcessing to false it should stay false
            allowEventProcessing = allowEventProcessing && !layer.SkipNextLayer;

            //Reset the layer's HandledEvents for this frame, this is done last to reset without iterating again.
            //Doing this last also ensures that if we stopped early on one of the fire events below that that layer
            //keeps its HandledEvents property set where it should be.
            layer.HandledEvents = false;
            return(allowEventProcessing);
        }
        /// <summary>
        /// Internal method to make sure all the buttons for the event are pressed.
        /// </summary>
        /// <param name="eventManager">The event manager with the keyboard and mouse being used.</param>
        /// <returns>True if all the required buttons are pressed.</returns>
        private ButtonScanResult scanButtons(EventLayer eventLayer)
        {
            Mouse    mouse              = eventLayer.Mouse;
            Keyboard keyboard           = eventLayer.Keyboard;
            Gamepad  pad                = eventLayer.getGamepad(this.pad);
            bool     allActivated       = keyboardButtons.Count + mouseButtons.Count + gamepadButtons.Count > 0 || MouseWheelDirection > 0;
            bool     anyDownUpThisFrame = false;
            bool     currentDownUpThisFrame;

            if (allActivated)
            {
                foreach (KeyboardButtonCode keyCode in keyboardButtons)
                {
                    allActivated &= keyboard.isKeyDown(keyCode);
                    if (!allActivated)
                    {
                        break;
                    }
                }
                if (allActivated)
                {
                    foreach (var keyCode in gamepadButtons)
                    {
                        allActivated &= pad.isButtonDown(keyCode);
                        if (!allActivated)
                        {
                            break;
                        }
                    }
                }
                if (allActivated)
                {
                    foreach (MouseButtonCode mouseCode in mouseButtons)
                    {
                        currentDownUpThisFrame = mouse.buttonDownAndUpThisFrame(mouseCode);
                        allActivated          &= (mouse.buttonDown(mouseCode) || currentDownUpThisFrame);
                        if (!allActivated)
                        {
                            break;
                        }
                        anyDownUpThisFrame |= currentDownUpThisFrame;
                    }
                }
                if (allActivated)
                {
                    switch (MouseWheelDirection)
                    {
                    case MouseWheelDirection.Up:
                        allActivated &= mouse.RelativePosition.z > 0;
                        break;

                    case MouseWheelDirection.Down:
                        allActivated &= mouse.RelativePosition.z < 0;
                        break;
                    }
                }
            }
            if (allActivated)
            {
                if (anyDownUpThisFrame)
                {
                    return(ButtonScanResult.DownAndUpThisFrame);
                }
                return(ButtonScanResult.Down);
            }
            else
            {
                return(ButtonScanResult.Up);
            }
        }
        /// <summary>
        /// Called internally to manage status of the event.
        /// </summary>
        protected internal override void update(EventLayer eventLayer, bool allowProcessing, Clock clock)
        {
            switch (scanButtons(eventLayer))
            {
            case ButtonScanResult.Down:
                if (FirstFrameDown)
                {
                    HeldDown       = true;
                    FirstFrameDown = false;
                }

                if (HeldDown)
                {
                    if (OnHeldDown != null)
                    {
                        OnHeldDown.Invoke(eventLayer);
                    }
                    if (OnDown != null)
                    {
                        OnDown.Invoke(eventLayer);
                    }
                }
                else
                {
                    FirstFrameDown = true;
                    if (FirstFrameDownEvent != null)
                    {
                        FirstFrameDownEvent.Invoke(eventLayer);
                    }
                    if (OnDown != null)
                    {
                        OnDown.Invoke(eventLayer);
                    }
                }
                FirstFrameUp = false;
                ReleasedUp   = false;
                break;

            case ButtonScanResult.Up:
                if (FirstFrameUp)
                {
                    ReleasedUp   = true;
                    FirstFrameUp = false;
                }
                else if (!ReleasedUp)
                {
                    FirstFrameUp = true;
                    if (FirstFrameUpEvent != null)
                    {
                        FirstFrameUpEvent.Invoke(eventLayer);
                    }
                }
                FirstFrameDown = false;
                HeldDown       = false;
                break;

            case ButtonScanResult.DownAndUpThisFrame:
                DownAndUpThisFrame = true;
                FirstFrameDown     = true;
                if (FirstFrameDownEvent != null)
                {
                    FirstFrameDownEvent.Invoke(eventLayer);
                }
                FirstFrameUp   = true;
                FirstFrameDown = false;
                if (FirstFrameUpEvent != null)
                {
                    FirstFrameUpEvent.Invoke(eventLayer);
                }
                ReleasedUp         = false;
                HeldDown           = false;
                DownAndUpThisFrame = false;
                break;
            }
        }
 /// <summary>
 /// Set the focus layer overriding any existing focus layer.
 /// </summary>
 internal void setFocusLayer(EventLayer layer)
 {
     focusLayer = layer;
 }
 /// <summary>
 /// The update function, do not call this outside EventManager.
 /// </summary>
 /// <param name="eventLayer"></param>
 /// <param name="allowProcessing"></param>
 protected internal abstract void update(EventLayer eventLayer, bool allowProcessing, Clock clock);
Exemple #9
0
        protected internal override void update(EventLayer eventLayer, bool allowProcessing, Clock clock)
        {
            var touches = eventLayer.EventManager.Touches;
            var fingers = touches.Fingers;

            if (fingers.Count == fingerCount)
            {
                Vector2 primaryFingerVec = new Vector2(fingers[0].PixelDeltaX, fingers[0].PixelDeltaY);
                float   primaryFingerLen = primaryFingerVec.length();
                Vector2 longestLengthVec = primaryFingerVec;
                float   longestLength    = primaryFingerLen;
                if (primaryFingerLen > 0)
                {
                    bool allVectorsSameDirection = true;
                    for (int i = 1; i < fingerCount && allVectorsSameDirection; ++i)
                    {
                        Vector2 testFingerVec = new Vector2(fingers[i].PixelDeltaX, fingers[i].PixelDeltaY);
                        float   testFingerLen = testFingerVec.length();
                        if (testFingerLen > 0)
                        {
                            float cosTheta = primaryFingerVec.dot(ref testFingerVec) / (primaryFingerLen * testFingerLen);
                            if (cosTheta > 0.5f)
                            {
                                if (testFingerLen > longestLength)
                                {
                                    longestLengthVec = testFingerVec;
                                    longestLength    = testFingerLen;
                                }
                            }
                            else
                            {
                                allVectorsSameDirection = false;
                            }
                        }
                    }
                    if (allVectorsSameDirection)
                    {
                        DeltaX    = longestLengthVec.x;
                        DeltaY    = longestLengthVec.y;
                        AbsoluteX = fingers[0].PixelX;
                        AbsoluteY = fingers[0].PixelY;

                        if (!gestureStarted)
                        {
                            cancelMomentum();

                            gestureStarted = true;
                            if (GestureStarted != null)
                            {
                                GestureStarted.Invoke(eventLayer, this);
                            }
                        }

                        didGesture = true;
                        averageSpeed[averageSpeedCursor] = longestLengthVec;
                        averageSpeedCursor++;
                        averageSpeedCursor %= averageSpeed.Length;

                        //Make sure to fire event last so momentum can be canceled if needed
                        if (Dragged != null)
                        {
                            Dragged.Invoke(eventLayer, this);
                        }
                    }
                }
                else if (gestureStarted)
                {
                    //If we have done the gesture once and the correct number of fingers are down, keep reporting that we did the gesture
                    didGesture = true;
                }
            }

            if (!didGesture)
            {
                if (gestureStarted)
                {
                    momentumStarted = true;
                    momentum        = new IntVector2(0, 0);
                    for (int i = 0; i < averageSpeed.Length; ++i)
                    {
                        momentum += averageSpeed[i];
                    }
                    momentum /= averageSpeed.Length;

                    momentumDirection = new Vector2(1.0f, 1.0f);
                    if (momentum.x < 0.0f)
                    {
                        momentum.x          = -momentum.x;
                        momentumDirection.x = -1.0f;
                    }
                    if (momentum.y < 0.0f)
                    {
                        momentum.y          = -momentum.y;
                        momentumDirection.y = -1.0f;
                    }
                    if (momentum.x < minimumMomentum)
                    {
                        momentum.x = 0.0f;
                    }
                    if (momentum.y < minimumMomentum)
                    {
                        momentum.y = 0.0f;
                    }
                    deceleration = momentum / decelerationTime;

                    //Important to fire event last so momentum can be canceled if needed
                    if (MomentumStarted != null)
                    {
                        MomentumStarted(eventLayer, this);
                    }
                }
                gestureStarted = false;

                if (momentum.length2() != 0.0f)
                {
                    momentum -= deceleration * clock.DeltaSeconds;
                    if (momentum.x < 0.0f)
                    {
                        momentum.x = 0.0f;
                    }
                    if (momentum.y <= 0.0f)
                    {
                        momentum.y = 0.0f;
                    }

                    Vector2 finalMomentum = momentum * momentumDirection;
                    DeltaX = finalMomentum.x;
                    DeltaY = finalMomentum.y;

                    if (Dragged != null)
                    {
                        Dragged.Invoke(eventLayer, this);
                    }
                }
                else if (momentumStarted)
                {
                    momentumStarted = false;
                    if (MomentumEnded != null)
                    {
                        MomentumEnded.Invoke(eventLayer, this);
                    }
                }
            }

            didGesture = false;
        }
        protected internal override void update(EventLayer eventLayer, bool allowProcessing, Clock clock)
        {
            var touches = eventLayer.EventManager.Touches;
            var fingers = touches.Fingers;

            if (fingers.Count == 2)
            {
                Finger  finger1    = fingers[0];
                Finger  finger2    = fingers[1];
                Vector2 finger1Vec = new Vector2(finger1.NrmlDeltaX, finger1.NrmlDeltaY);
                Vector2 finger2Vec = new Vector2(finger2.NrmlDeltaX, finger2.NrmlDeltaY);
                float   finger1Len = finger1Vec.length2();
                float   finger2Len = finger2Vec.length2();
                if (finger1Len > 0 || finger2Len > 0)
                {
                    if (finger1Len > 0 && finger2Len > 0)
                    {
                        float cosTheta = finger1Vec.dot(ref finger2Vec) / (finger1Vec.length() * finger2Vec.length());
                        if (cosTheta < -0.5f && Zoom != null)
                        {
                            computeZoom(eventLayer, ref didGesture, finger1, finger2, ref finger1Vec, ref finger2Vec);
                        }
                    }
                    else if (finger1Len == 0 && finger2Len > 0)
                    {
                        computeZoom(eventLayer, ref didGesture, finger1, finger2, ref finger1Vec, ref finger2Vec);
                    }
                    else if (finger2Len == 0 && finger1Len > 0)
                    {
                        computeZoom(eventLayer, ref didGesture, finger1, finger2, ref finger1Vec, ref finger2Vec);
                    }
                }
            }

            //Momentum
            if (!didGesture)
            {
                if (momentum > 0.0f)
                {
                    zoomDelta = momentum * momentumDirection;

                    if (!momentumStarted)
                    {
                        momentumStarted = true;
                        if (MomentumStarted != null)
                        {
                            MomentumStarted.Invoke(eventLayer, this);
                        }
                    }

                    momentum -= deceleration * clock.DeltaSeconds;
                    if (momentum < 0.0f)
                    {
                        momentum = 0.0f;
                    }
                    if (Zoom != null)
                    {
                        Zoom.Invoke(eventLayer, this);
                    }
                }
                else if (momentumStarted)
                {
                    zoomDelta = 0.0f;

                    momentumStarted = false;
                    gestureStarted  = false;
                    if (MomentumEnded != null)
                    {
                        MomentumEnded.Invoke(eventLayer, this);
                    }
                }
            }
            didGesture = false;
        }