Exemplo n.º 1
0
 bool INavigatableControl.OnNavigationMovement(UINavigationInputMovement inputMovement) => false;
        private void HandleInputMovement(List <UINavControl> allActiveControls, List <UINavControl> allActiveControlsExclSelected)
        {
            bool isTabPressed   = _inputManager.IsKeyPressed(Keys.Tab);
            bool isShiftKeyDown = _inputManager.IsKeyDown(Keys.LeftShift) || _inputManager.IsKeyDown(Keys.RightShift);

            if (_inputManager.HasGamePad && _inputManager.DefaultGamePad != null)
            {
                var gamePad = _inputManager.DefaultGamePad;
                if (gamePad.IsButtonPressed(GamePadButton.LeftShoulder))
                {
                    // Treat as shift + tab
                    isTabPressed   = true;
                    isShiftKeyDown = true;
                }
                else if (gamePad.IsButtonPressed(GamePadButton.RightShoulder))
                {
                    // Treat as tab
                    isTabPressed = true;
                }
            }
            if (_selectedControl.Control != null && isTabPressed)
            {
                var navMmnt = new UINavigationInputMovement
                {
                    InputType      = isShiftKeyDown ? UINavigationInputType.ShiftTab : UINavigationInputType.Tab,
                    InputDirection = Vector2.Zero
                };
                if (_selectedControl.Control.OnNavigationMovement(navMmnt))
                {
                    // Current control has handled the input
                    return;
                }
            }

            // UI is in screen space where origin is top left corner of the screen, x-axis pointing left, y-axis pointing down
            var inputDir = Vector2.Zero;        // Vector2 is used since in the future we could possibly implement thumbstick controller input.

            inputDir.X += _inputManager.IsKeyPressed(Keys.Left) ? -1 : 0;
            inputDir.X += _inputManager.IsKeyPressed(Keys.Right) ? 1 : 0;
            inputDir.Y += _inputManager.IsKeyPressed(Keys.Up) ? -1 : 0;
            inputDir.Y += _inputManager.IsKeyPressed(Keys.Down) ? 1 : 0;

            if (_inputManager.HasGamePad && _inputManager.DefaultGamePad != null)
            {
                var gamePad = _inputManager.DefaultGamePad;
                inputDir.X += gamePad.IsButtonPressed(GamePadButton.PadLeft) ? -1 : 0;
                inputDir.X += gamePad.IsButtonPressed(GamePadButton.PadRight) ? 1 : 0;
                inputDir.Y += gamePad.IsButtonPressed(GamePadButton.PadUp) ? -1 : 0;
                inputDir.Y += gamePad.IsButtonPressed(GamePadButton.PadDown) ? 1 : 0;
            }

            if (inputDir.LengthSquared() > 0)
            {
                inputDir.Normalize();
            }
            if (_selectedControl.Control != null && inputDir.LengthSquared() > 0)
            {
                var navMmnt = new UINavigationInputMovement
                {
                    InputType      = UINavigationInputType.Input,
                    InputDirection = inputDir
                };
                if (_selectedControl.Control.OnNavigationMovement(navMmnt))
                {
                    // Current control has handled the input
                    return;
                }
            }

            if (isTabPressed)
            {
                // Treat tabbing as left/right movement
                float shiftValue = isShiftKeyDown ? -1 : 1;
                inputDir.X += shiftValue * 1;
                if (inputDir.LengthSquared() > 0)
                {
                    inputDir.Normalize();
                }
            }

            if (inputDir.LengthSquared() > 0)
            {
                if (_selectedControl.UIElement == null)
                {
                    // Just pick the first control
                    if (allActiveControls.Count > 0)
                    {
                        // Sort top to bottom, left to right
                        allActiveControls.Sort((ctrl1, ctrl2) =>
                        {
                            // Use the top-left corner of the UI as the sorting position, as this should
                            // account for different sized UI

                            var ctrl1Pos    = ctrl1.UIElement.WorldMatrix.TranslationVector;
                            float ctrl1Left = ctrl1Pos.X - (ctrl1.UIElement.RenderSize.X * 0.5f);
                            float ctrl1Top  = ctrl1Pos.Y - (ctrl1.UIElement.RenderSize.Y * 0.5f);

                            var ctrl2Pos    = ctrl2.UIElement.WorldMatrix.TranslationVector;
                            float ctrl2Left = ctrl2Pos.X - (ctrl2.UIElement.RenderSize.X * 0.5f);
                            float ctrl2Top  = ctrl2Pos.Y - (ctrl2.UIElement.RenderSize.Y * 0.5f);
                            if (ctrl1Top < ctrl2Top)
                            {
                                return(-1);
                            }
                            else if (ctrl1Top > ctrl2Top)
                            {
                                return(1);
                            }
                            else
                            {
                                return(ctrl1Left.CompareTo(ctrl2Left));
                            }
                        });
                        SetControlAsSelected(allActiveControls[0]);
                    }
                    //else  // Nothing to select
                }
                else if (allActiveControlsExclSelected.Count > 0)
                {
                    var uiWorldMatrix    = _selectedControl.UIElement.WorldMatrix;
                    var originUIPosition = uiWorldMatrix.TranslationVector.XY();
                    if (Math.Abs(inputDir.X) >= Math.Abs(inputDir.Y))
                    {
                        // Sort top to bottom, left to right
                        allActiveControls.Sort((ctrl1, ctrl2) =>
                        {
                            // Use the top-left corner of the UI as the sorting position, as this should
                            // account for different sized UI

                            var ctrl1Pos    = ctrl1.UIElement.WorldMatrix.TranslationVector;
                            float ctrl1Left = ctrl1Pos.X - (ctrl1.UIElement.RenderSize.X * 0.5f);
                            float ctrl1Top  = ctrl1Pos.Y - (ctrl1.UIElement.RenderSize.Y * 0.5f);

                            var ctrl2Pos    = ctrl2.UIElement.WorldMatrix.TranslationVector;
                            float ctrl2Left = ctrl2Pos.X - (ctrl2.UIElement.RenderSize.X * 0.5f);
                            float ctrl2Top  = ctrl2Pos.Y - (ctrl2.UIElement.RenderSize.Y * 0.5f);
                            if (ctrl1Top < ctrl2Top)
                            {
                                return(-1);
                            }
                            else if (ctrl1Top > ctrl2Top)
                            {
                                return(1);
                            }
                            else
                            {
                                return(ctrl1Left.CompareTo(ctrl2Left));
                            }
                        });
                        int curSelectedIndex  = allActiveControls.IndexOf(x => x.Control == _selectedControl.Control);
                        int nextSelectedIndex = curSelectedIndex + (inputDir.X > 0 ? 1 : -1);
                        if (nextSelectedIndex < 0)
                        {
                            nextSelectedIndex = allActiveControls.Count - 1;
                        }
                        else if (nextSelectedIndex == allActiveControls.Count)
                        {
                            nextSelectedIndex = 0;
                        }
                        if (nextSelectedIndex != curSelectedIndex)
                        {
                            SetControlAsSelected(allActiveControls[nextSelectedIndex]);
                        }
                    }
                    else
                    {
                        // Sort left to right, top to bottom
                        allActiveControls.Sort((ctrl1, ctrl2) =>
                        {
                            // Use the top-left corner of the UI as the sorting position, as this should
                            // account for different sized UI

                            var ctrl1Pos    = ctrl1.UIElement.WorldMatrix.TranslationVector;
                            float ctrl1Left = ctrl1Pos.X - (ctrl1.UIElement.RenderSize.X * 0.5f);
                            float ctrl1Top  = ctrl1Pos.Y - (ctrl1.UIElement.RenderSize.Y * 0.5f);

                            var ctrl2Pos    = ctrl2.UIElement.WorldMatrix.TranslationVector;
                            float ctrl2Left = ctrl2Pos.X - (ctrl2.UIElement.RenderSize.X * 0.5f);
                            float ctrl2Top  = ctrl2Pos.Y - (ctrl2.UIElement.RenderSize.Y * 0.5f);
                            if (ctrl1Left < ctrl2Left)
                            {
                                return(-1);
                            }
                            else if (ctrl1Left > ctrl2Left)
                            {
                                return(1);
                            }
                            else
                            {
                                return(ctrl1Top.CompareTo(ctrl1Top));
                            }
                        });
                        int curSelectedIndex  = allActiveControls.IndexOf(x => x.Control == _selectedControl.Control);
                        int nextSelectedIndex = curSelectedIndex + (inputDir.Y > 0 ? 1 : -1);
                        if (nextSelectedIndex < 0)
                        {
                            nextSelectedIndex = allActiveControls.Count - 1;
                        }
                        else if (nextSelectedIndex == allActiveControls.Count)
                        {
                            nextSelectedIndex = 0;
                        }
                        if (nextSelectedIndex != curSelectedIndex)
                        {
                            SetControlAsSelected(allActiveControls[nextSelectedIndex]);
                        }
                    }
                }

                _nextControlCandidates.Clear();
            }
        }