Пример #1
0
        private void UpdateMouseOver(UIComponentProcessor.UIComponentState state)
        {
            if (input == null || !input.HasMouse)
            {
                return;
            }

            var intersectionPoint = Vector3.Zero;
            var mousePosition     = input.MousePosition;
            var rootElement       = state.UIComponent.RootElement;
            var lastOveredElement = state.LastOveredElement;
            var overredElement    = lastOveredElement;

            // determine currently overred element.
            if (mousePosition != lastMousePosition)
            {
                overredElement = GetElementAtScreenPosition(rootElement, mousePosition, ref intersectionPoint);
            }

            // find the common parent between current and last overred elements
            var commonElement = FindCommonParent(overredElement, lastOveredElement);

            // disable mouse over state to previously overred hierarchy
            var parent = lastOveredElement;

            while (parent != commonElement && parent != null)
            {
                parent.MouseOverState = MouseOverState.MouseOverNone;
                parent = parent.VisualParent;
            }

            // enable mouse over state to currently overred hierarchy
            if (overredElement != null)
            {
                // the element itself
                overredElement.MouseOverState = MouseOverState.MouseOverElement;

                // its hierarchy
                parent = overredElement.VisualParent;
                while (parent != null)
                {
                    if (parent.IsHierarchyEnabled)
                    {
                        parent.MouseOverState = MouseOverState.MouseOverChild;
                    }

                    parent = parent.VisualParent;
                }
            }

            // update cached values
            state.LastOveredElement = overredElement;
            lastMousePosition       = mousePosition;
        }
Пример #2
0
        private void UpdateTouchEvents(UIComponentProcessor.UIComponentState state, GameTime gameTime)
        {
            var rootElement       = state.UIComponent.RootElement;
            var intersectionPoint = Vector3.Zero;
            var lastTouchPosition = new Vector2(float.NegativeInfinity);

            // analyze pointer event input and trigger UI touch events depending on hit Tests
            foreach (var pointerEvent in compactedPointerEvents)
            {
                // performance optimization: skip all the events that started outside of the UI
                var lastTouchedElement = state.LastTouchedElement;
                if (lastTouchedElement == null && pointerEvent.State != PointerState.Down)
                {
                    continue;
                }

                var time = gameTime.Total;

                var currentTouchPosition  = pointerEvent.Position;
                var currentTouchedElement = lastTouchedElement;

                // re-calculate the element under cursor if click position changed.
                if (lastTouchPosition != currentTouchPosition)
                {
                    currentTouchedElement = GetElementAtScreenPosition(rootElement, pointerEvent.Position, ref intersectionPoint);
                }

                if (pointerEvent.State == PointerState.Down || pointerEvent.State == PointerState.Up)
                {
                    state.LastIntersectionPoint = intersectionPoint;
                }

                var touchEvent = new TouchEventArgs
                {
                    Action            = TouchAction.Down,
                    Timestamp         = time,
                    ScreenPosition    = currentTouchPosition,
                    ScreenTranslation = pointerEvent.DeltaPosition,
                    WorldPosition     = intersectionPoint,
                    WorldTranslation  = intersectionPoint - state.LastIntersectionPoint
                };

                switch (pointerEvent.State)
                {
                case PointerState.Down:
                    touchEvent.Action = TouchAction.Down;
                    if (currentTouchedElement != null)
                    {
                        currentTouchedElement.RaiseTouchDownEvent(touchEvent);
                    }
                    break;

                case PointerState.Up:
                    touchEvent.Action = TouchAction.Up;

                    // generate enter/leave events if we passed from an element to another without move events
                    if (currentTouchedElement != lastTouchedElement)
                    {
                        ThrowEnterAndLeaveTouchEvents(currentTouchedElement, lastTouchedElement, touchEvent);
                    }

                    // trigger the up event
                    if (currentTouchedElement != null)
                    {
                        currentTouchedElement.RaiseTouchUpEvent(touchEvent);
                    }
                    break;

                case PointerState.Move:
                    touchEvent.Action = TouchAction.Move;

                    // first notify the move event (even if the touched element changed in between it is still coherent in one of its parents)
                    if (currentTouchedElement != null)
                    {
                        currentTouchedElement.RaiseTouchMoveEvent(touchEvent);
                    }

                    // then generate enter/leave events if we passed from an element to another
                    if (currentTouchedElement != lastTouchedElement)
                    {
                        ThrowEnterAndLeaveTouchEvents(currentTouchedElement, lastTouchedElement, touchEvent);
                    }
                    break;

                case PointerState.Out:
                case PointerState.Cancel:
                    touchEvent.Action = TouchAction.Move;

                    // generate enter/leave events if we passed from an element to another without move events
                    if (currentTouchedElement != lastTouchedElement)
                    {
                        ThrowEnterAndLeaveTouchEvents(currentTouchedElement, lastTouchedElement, touchEvent);
                    }

                    // then raise leave event to all the hierarchy of the previously selected element.
                    var element = currentTouchedElement;
                    while (element != null)
                    {
                        if (element.IsTouched)
                        {
                            element.RaiseTouchLeaveEvent(touchEvent);
                        }
                        element = element.VisualParent;
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                lastTouchPosition           = currentTouchPosition;
                state.LastTouchedElement    = currentTouchedElement;
                state.LastIntersectionPoint = intersectionPoint;
            }
        }