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(); } }