View Issue Details

IDProjectCategoryView StatusLast Update
0001604NoesisGUIUnitypublic2019-12-19 17:53
Reporterstonstad Assigned Tosfernandez  
PrioritynormalSeveritymajor 
Status resolvedResolutionfixed 
Product Version2.2.5 
Target Version2.2.6Fixed in Version2.2.6 
Summary0001604: Keyboard/Joystick Selection Fails If Intermediary UI Element Collapsed
Description

Given N focusable controls, if a control with index > 1 and < N is collapsed, keyboard and gamepad focus cannot move beyond the collapsed element. Tab selection works but keyboard (and gamepad) selection does not work. In the attached video, the following is shown:

  1. All buttons are displayed. Gamepad selection and focus may traverse all visible buttons.
  2. Buttons are collapsed in the middle of the container.
  3. Selection may not proceed beyond the element preceding the collapsed buttons.
  4. However, tab focus and selection still works.

Video:
http://stellarconquest.blob.core.windows.net/$root/Selection%20Bug.mp4

Encl. Identity Selection Control.xaml

We are submitting this as major because it is currently a release blocker for the XBOX platform and SC Alpha 2 release.

Attached Files
IdentitySelectionControl.cs (22,813 bytes)   
using Noesis;
using StellarConquest.Model.Extensions;
using StellarConquest.Model.Factions;
using StellarConquest.Model.Players;
using System;
using UnityEngine;
using EventArgs = Noesis.EventArgs;
using Grid = Noesis.Grid;
using GUI = Noesis.GUI;
using Random = UnityEngine.Random;

namespace StellarConquest.Presentation.Unity.UI
{
    public partial class IdentitySelectionControl : UserControl, ICharacterCreationControl
    {
        public CharacterCreationScreen CharacterCreationScreen { get; set; }

        private TextBox _PlayerNameTextBox;
        private RenderControl _RenderControl;
        private bool _RenderControlCreated = false;

        private GameObject _CharacterGameObject;
        private CharacterCustomization _CharacterCustomization;
        private SpeciesType _Species = SpeciesType.HumanMale;
        private VariationType _Variation = VariationType.Other;
        private OutfitType _Outfit = OutfitType.Colonist;

        private Button _LeftSpeciesButton;
        private Button _RightSpeciesButton;
        private Button _LeftVariationButton;
        private Button _RightVariationButton;
        private Button _LeftOutfitButton;
        private Button _RightOutfitButton;

        private Button _LeftHairStyleButton;
        private Button _RightHairStyleButton;
        private Button _LeftHairColorButton;
        private Button _RightHairColorButton;
        private Button _LeftHeadButton;
        private Button _RightHeadButton;
        private Button _LeftTorsoButton;
        private Button _RightTorsoButton;
        private Button _LeftPantsButton;
        private Button _RightPantsButton;
        private Button _LeftBootsButton;
        private Button _RightBootsButton;
        private Button _LeftTopArmorButton;
        private Button _RightTopArmorButton;
        private Button _LeftBottomArmorButton;
        private Button _RightBottomArmorButton;
        private Button _LeftInsigniaStyleButton;
        private Button _RightInsigniaStyleButton;
        private Button _LeftInsigniaColorButton;
        private Button _RightInsigniaColorButton;

        private Button _RandomizeButton;

        private Grid _OutfitGrid;
        private Grid _HeadGrid;
        private Grid _HairStyleGrid;
        private Grid _HairColorGrid;
        private Grid _BootsGrid;
        private Grid _TopArmorGrid;
        private Grid _BottomArmorGrid;
        private Grid _InsigniaStyleGrid;
        private Grid _InsigniaColorGrid;

        private Vector3 _BodyPosition = new Vector3(0, -0.45f, 0.85f);
        private Vector3 _HeadPosition = new Vector3(0, -0.78f, 0.315f);
        private Vector3 _TorsoPosition = new Vector3(0, -0.63f, 0.4f);
        private Vector3 _PantsPosition = new Vector3(0, -0.33f, 0.4f);
        private Vector3 _BootsPosition = new Vector3(0, -0.21f, 0.4f);

        public IdentitySelectionControl()
        {
            if (!Application.isPlaying)
                return;

            this.Initialized += OnInitialized;
            this.InitializeComponent();
        }

        private void InitializeComponent()
        {
            GUI.LoadComponent(this, "Assets/User Interface/Screens/Character Creation/Identity/IdentitySelectionControl.xaml");
            FrameworkElement root = this.Content as FrameworkElement;
            _PlayerNameTextBox = root.FindName("_PlayerNameTextBox") as TextBox;
            _RenderControl = root.FindName("_RenderControl") as RenderControl;

            _LeftSpeciesButton = root.FindName("_LeftSpeciesButton") as Button;
            _RightSpeciesButton = root.FindName("_RightSpeciesButton") as Button;
            _LeftOutfitButton = root.FindName("_LeftOutfitButton") as Button;
            _RightOutfitButton = root.FindName("_RightOutfitButton") as Button;
            _LeftVariationButton = root.FindName("_LeftVariationButton") as Button;
            _RightVariationButton = root.FindName("_RightVariationButton") as Button;
            _LeftHairStyleButton = root.FindName("_LeftHairStyleButton") as Button;
            _RightHairStyleButton = root.FindName("_RightHairStyleButton") as Button;
            _LeftHairColorButton = root.FindName("_LeftHairColorButton") as Button;
            _RightHairColorButton = root.FindName("_RightHairColorButton") as Button;
            _LeftHeadButton = root.FindName("_LeftHeadButton") as Button;
            _RightHeadButton = root.FindName("_RightHeadButton") as Button;
            _LeftTorsoButton = root.FindName("_LeftTorsoButton") as Button;
            _RightTorsoButton = root.FindName("_RightTorsoButton") as Button;
            _LeftPantsButton = root.FindName("_LeftPantsButton") as Button;
            _RightPantsButton = root.FindName("_RightPantsButton") as Button;
            _LeftBootsButton = root.FindName("_LeftBootsButton") as Button;
            _RightBootsButton = root.FindName("_RightBootsButton") as Button;
            _LeftTopArmorButton = root.FindName("_LeftTopArmorButton") as Button;
            _RightTopArmorButton = root.FindName("_RightTopArmorButton") as Button;
            _LeftBottomArmorButton = root.FindName("_LeftBottomArmorButton") as Button;
            _RightBottomArmorButton = root.FindName("_RightBottomArmorButton") as Button;
            _LeftInsigniaStyleButton = root.FindName("_LeftInsigniaStyleButton") as Button;
            _RightInsigniaStyleButton = root.FindName("_RightInsigniaStyleButton") as Button;
            _LeftInsigniaColorButton = root.FindName("_LeftInsigniaColorButton") as Button;
            _RightInsigniaColorButton = root.FindName("_RightInsigniaColorButton") as Button;

            _RandomizeButton = root.FindName("_RandomizeButton") as Button;

            _OutfitGrid = root.FindName("_OutfitGrid") as Grid;
            _HeadGrid = root.FindName("_HeadGrid") as Grid;
            _HairStyleGrid = root.FindName("_HairStyleGrid") as Grid;
            _HairColorGrid = root.FindName("_HairColorGrid") as Grid;
            _BootsGrid = root.FindName("_BootsGrid") as Grid;
            _TopArmorGrid = root.FindName("_TopArmorGrid") as Grid;
            _BottomArmorGrid = root.FindName("_BottomArmorGrid") as Grid;
            _InsigniaStyleGrid = root.FindName("_InsigniaStyleGrid") as Grid;
            _InsigniaColorGrid = root.FindName("_InsigniaColorGrid") as Grid;

            // species
            _LeftSpeciesButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                PreviousSpecies();
                _RenderControl.SetPosition(_BodyPosition);
            };
            _RightSpeciesButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                NextSpecies();
                _RenderControl.SetPosition(_BodyPosition);
            };

            // variation
            _LeftVariationButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                PreviousVariation();
                _RenderControl.SetPosition(_BodyPosition);
            };
            _RightVariationButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                NextVariation();
                _RenderControl.SetPosition(_BodyPosition);
            };

            // outfit
            _LeftOutfitButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                PreviousOutfit();
                _RenderControl.SetPosition(_BodyPosition);
            };
            _RightOutfitButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                NextOutfit();
                _RenderControl.SetPosition(_BodyPosition);
            };

            // aesthetic attributes
            _LeftHairStyleButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousHairStyle();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _RightHairStyleButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextHairStyle();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _LeftHairColorButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousHairColor();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _RightHairColorButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextHairColor();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _LeftHeadButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousHead();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _RightHeadButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextHead();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _LeftTorsoButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousTorso();
                _RenderControl.SetPosition(_TorsoPosition);
            };
            _RightTorsoButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextTorso();
                _RenderControl.SetPosition(_TorsoPosition);
            };
            _LeftPantsButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousPants();
                _RenderControl.SetPosition(_PantsPosition);
            };
            _RightPantsButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextPants();
                _RenderControl.SetPosition(_PantsPosition);
            };
            _LeftBootsButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousBoots();
                _RenderControl.SetPosition(_BootsPosition);
            };
            _RightBootsButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextBoots();
                _RenderControl.SetPosition(_BootsPosition);
            };
            _LeftTopArmorButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousTopArmor();
                _RenderControl.SetPosition(_TorsoPosition);
            };
            _RightTopArmorButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextTopArmor();
                _RenderControl.SetPosition(_TorsoPosition);
            };
            _LeftBottomArmorButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousBottomArmor();
                _RenderControl.SetPosition(_PantsPosition);
            };
            _RightBottomArmorButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextBottomArmor();
                _RenderControl.SetPosition(_PantsPosition);
            };
            _LeftInsigniaStyleButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousPinStyle();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _RightInsigniaStyleButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextPinStyle();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _LeftInsigniaColorButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.PreviousPinColor();
                _RenderControl.SetPosition(_HeadPosition);
            };
            _RightInsigniaColorButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                _CharacterCustomization.NextPinColor();
                _RenderControl.SetPosition(_HeadPosition);
            };


            _RandomizeButton.Click += (sender, e) =>
            {
                GameState.Instance.StaticAudioEffects.ButtonClick();
                Randomize();
                _RenderControl.SetPosition(_BodyPosition);
            };

#if (UNITY_EDITOR)
            _PlayerNameTextBox.Text = "Tester " + Random.Range(1000, 9999);
#endif
            _PlayerNameTextBox.GotFocus += (sender, e) => _RenderControl.SetPosition(_BodyPosition);
        }

        private void OnInitialized(object sender, EventArgs args)
        {
            _PlayerNameTextBox.TextChanged += (sender2, e2) => Validate();
        }

        public void Show()
        {
            Validate();

            if (!_RenderControlCreated)
            {
                _RenderControlCreated = true;
                Load(_Species, _Variation, _Outfit);
            }
            else
            {
                ConfigureRenderControl();
                _RenderControl.Enable();
            }
        }

        public void Hide()
        {
            CharacterCreationScreen.CharacterSheet.PlayerName = _PlayerNameTextBox.Text;
            CharacterCreationScreen.CharacterSheet.RaceId = BaseFaction.GetFactionDefaultRaceId(CharacterCreationScreen.CharacterSheet.FactionId);
            CharacterCreationScreen.CharacterSheet.Appearance = _CharacterCustomization.GetConfiguration();
            _RenderControl.Disable();
        }

        private void Validate()
        {
            string text = _PlayerNameTextBox.Text;
            bool isValid = !string.IsNullOrEmpty(text) && text.Trim().Length >= 4;
            CharacterCreationScreen.SetNextButtonState(isValid);
        }

        private void Load(SpeciesType species, VariationType variation, OutfitType outfit)
        {
            switch (species)
            {
                case SpeciesType.HumanMale:
                    _OutfitGrid.Visibility = Visibility.Visible;
                    _HeadGrid.Visibility = Visibility.Visible;
                    _HairStyleGrid.Visibility = Visibility.Visible;
                    _HairColorGrid.Visibility = Visibility.Visible;
                    break;
                case SpeciesType.HumanFemale:
                    _OutfitGrid.Visibility = Visibility.Collapsed;
                    _HeadGrid.Visibility = Visibility.Visible;
                    _HairStyleGrid.Visibility = Visibility.Visible;
                    _HairColorGrid.Visibility = Visibility.Visible;
                    break;
                case SpeciesType.KethMale:
                    _OutfitGrid.Visibility = Visibility.Visible;
                    _HeadGrid.Visibility = Visibility.Collapsed;
                    _HairStyleGrid.Visibility = Visibility.Collapsed;
                    _HairColorGrid.Visibility = Visibility.Collapsed;
                    break;
                case SpeciesType.Synthetic:
                    break;
                case SpeciesType.Ouster:
                    break;
                default:
                    break;
            }

            switch (outfit)
            {
                case OutfitType.Colonist:
                    _BootsGrid.Visibility = Visibility.Collapsed;
                    _TopArmorGrid.Visibility = Visibility.Collapsed;
                    _BottomArmorGrid.Visibility = Visibility.Collapsed;
                    _InsigniaStyleGrid.Visibility = Visibility.Collapsed;
                    _InsigniaColorGrid.Visibility = Visibility.Collapsed;
                    break;
                case OutfitType.Imperium:
                    _BootsGrid.Visibility = Visibility.Visible;
                    _TopArmorGrid.Visibility = Visibility.Collapsed;
                    _BottomArmorGrid.Visibility = Visibility.Collapsed;
                    _InsigniaStyleGrid.Visibility = Visibility.Visible;
                    _InsigniaColorGrid.Visibility = Visibility.Visible;
                    break;
                case OutfitType.Soldier:
                    _BootsGrid.Visibility = Visibility.Visible;
                    _TopArmorGrid.Visibility = Visibility.Visible;
                    _BottomArmorGrid.Visibility = Visibility.Visible;
                    _InsigniaStyleGrid.Visibility = Visibility.Collapsed;
                    _InsigniaColorGrid.Visibility = Visibility.Collapsed;
                    break;
                default:
                    break;
            }


            PlayerAppearance previousAppearance = null;
            AnimatorStateInfo? previousAnimatorState = null;

            if (_CharacterGameObject != null)
            {
                CharacterCustomization previousCharacterCustomization = _CharacterCustomization.GetComponent<CharacterCustomization>();
                previousAppearance = previousCharacterCustomization.GetConfiguration();
                previousAnimatorState = previousCharacterCustomization.GetAnimatorState();
                GameObject.Destroy(_CharacterGameObject);
            }
            _CharacterGameObject = Factory.Instance.CreatePlayer(species, variation, outfit);
            _CharacterCustomization = _CharacterGameObject.AddComponent<CharacterCustomization>();
            _CharacterCustomization.SetController("character identity controller");
            if (previousAppearance != null)
                _CharacterCustomization.SetConfiguration(previousAppearance);
            else
                _CharacterCustomization.ResetConfiguration();

            // resume animation time
            if (previousAnimatorState.HasValue)
                UnityDispatcher.Instance.Invoke(() => _CharacterCustomization.SetAnimatorState(previousAnimatorState.Value));

            ConfigureRenderControl();
            _RenderControl.Enable();
        }

        private void ConfigureRenderControl()
        {
            _RenderControl.SetTargetGameObject(_CharacterGameObject, new Vector3(0.5f, 0.5f, 0.5f), _BodyPosition, Quaternion.Euler(0, 180, 0));
            _RenderControl.ConfigureCameraEffects(true, false, true);
            _RenderControl.ConfigureLight(LightType.Directional, 0.92f, true, Vector3.zero, Quaternion.Euler(45, -20, 0));
        }

        private void NextSpecies()
        {
            _Species++;
            if (_Species > SpeciesType.KethMale)
                _Species = 0;

            ClampOutfit(0);
            Load(_Species, _Variation, _Outfit);
        }

        private void PreviousSpecies()
        {
            _Species--;
            if (_Species < 0 || _Species > _Species.GetMaxValue()) // compare as non-negative byte (i.e. negative is 255)
                _Species = SpeciesType.KethMale;

            ClampOutfit(0);
            Load(_Species, _Variation, _Outfit);
        }

        private void NextVariation()
        {
        }

        private void PreviousVariation()
        {
        }

        private void NextOutfit()
        {
            _Outfit++;
            if (_Outfit > _Outfit.GetMaxValue())
                _Outfit = 0;

            ClampOutfit(1);
            Load(_Species, _Variation, _Outfit);
        }

        private void PreviousOutfit()
        {
            _Outfit--;
            if (_Outfit < 0 || _Outfit > _Outfit.GetMaxValue()) // compare as non-negative byte (i.e. negative is 255)
                _Outfit = _Outfit.GetMaxValue();

            ClampOutfit(-1);
            Load(_Species, _Variation, _Outfit);
        }

        private void ClampOutfit(int value)
        {
            switch (_Species)
            {
                case SpeciesType.HumanMale:
                    // do nothing -- all outfits supported
                    break;
                case SpeciesType.HumanFemale:
                    _Outfit = OutfitType.Imperium;
                    break;
                case SpeciesType.KethMale:
                    if (_Outfit == OutfitType.Colonist)
                    {
                        if (value == -1)
                            _Outfit = OutfitType.Soldier;
                        else if (value == 1)
                            _Outfit = OutfitType.Imperium;
                        else if (value == 0)
                            _Outfit = OutfitType.Soldier;
                    }
                    break;
                case SpeciesType.Synthetic:
                case SpeciesType.Ouster:
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        private void Randomize()
        {
            _Species = (SpeciesType)Random.Range(0, 3);
            _Outfit = (OutfitType)Random.Range(0, 3);
            ClampOutfit(0);

            Load(_Species, _Variation, _Outfit);
            _CharacterCustomization.SetRandomConfiguration(Random.Range(int.MinValue, int.MaxValue), true, true);
        }

        public void FocusChanged()
        {
            if (_RenderControl != null)
                _RenderControl.SetPosition(_BodyPosition);
        }
    }
}
IdentitySelectionControl.cs (22,813 bytes)   
IdentitySelectionControl.xaml (34,626 bytes)   
<UserControl
    x:Class="StellarConquest.Presentation.Unity.UI.IdentitySelectionControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
    xmlns:local="clr-namespace:StellarConquest.Presentation.Unity.UI"
    d:DesignWidth="640" d:DesignHeight="415">
    <Grid x:Name="_LayoutRoot">
        <local:BorderControl Title="NEW CHARACTER - IDENTITY" LeftBarVisibility="Collapsed" RightBarVisibility="Collapsed"/>

        <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="30, 54, 30, 24">
            <Grid Margin="0, 0, 26, 0">
                <local:RenderControl x:Name="_RenderControl" Width="1024" Height="1024" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="-80, -10, -80, -16">
                    <local:RenderControl.LayoutTransform>
                        <ScaleTransform ScaleX="0.75" ScaleY="0.75"/>
                    </local:RenderControl.LayoutTransform>
                </local:RenderControl>
            </Grid>
            <StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="0, -7, 30, 0">
                <TextBlock Text="Name" HorizontalAlignment="Left" Style="{StaticResource Heading3Primary}" Margin="0" />
                <TextBox x:Name="_PlayerNameTextBox" Width="300" FontSize="{StaticResource Heading3FontSize}"/>

                <StackPanel Orientation="Vertical" Margin="0, 5, 0, 0">
                    <!-- Randomize  -->
                    <Grid Margin="0, 17, 0, 0">
                        <Button x:Name="_RandomizeButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 287.743,487.708C 284.649,486.353 281.239,485.584 277.604,485.549C 277.035,485.544 276.475,485.567 275.916,485.602C 275.525,485.625 275.139,485.663 274.752,485.701C 274.691,485.708 274.629,485.711 274.568,485.717L 274.568,485.723C 270.041,486.217 265.856,487.867 262.339,490.4L 259.811,486.673C 259.661,486.455 259.399,486.349 259.141,486.404C 258.881,486.459 258.685,486.661 258.637,486.921L 257.068,495.58L 255.963,501.69C 255.925,501.887 255.98,502.084 256.113,502.234C 256.236,502.373 256.411,502.453 256.635,502.453L 263.5,502.088L 271.231,501.677C 271.491,501.663 271.715,501.497 271.805,501.251C 271.895,501.008 271.831,500.734 271.64,500.559L 268.449,497.549C 270.448,496.252 272.741,495.381 275.205,495.053L 275.211,495.127C 275.964,495.029 276.728,494.966 277.511,494.973C 286.673,495.065 294.027,502.567 293.935,511.728C 293.844,520.891 286.343,528.244 277.18,528.152C 268.019,528.061 260.664,520.56 260.755,511.397C 260.763,510.597 260.848,509.817 260.965,509.049L 252.128,505.713C 251.735,507.465 251.508,509.28 251.489,511.148C 251.347,525.43 262.808,537.122 277.088,537.264C 291.369,537.407 303.063,525.945 303.204,511.664C 303.309,501.027 296.975,491.836 287.836,487.773 Z "/>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Randomize" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>
                    
                    <!-- Species -->
                    <Grid Margin="0, 17, 0, 0">
                        <Button x:Name="_LeftSpeciesButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightSpeciesButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Type" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70" />
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Variation -->
                    <Grid Margin="0, 17, 0, 0" Visibility="Collapsed">
                        <Button x:Name="_LeftVariationButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightVariationButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Variation" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70" />
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Outfit -->
                    <Grid Margin="0, 17, 0, 0" x:Name="_OutfitGrid">
                        <Button x:Name="_LeftOutfitButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightOutfitButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Outfit" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70" />
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Hair Style -->
                    <Grid Margin="0, 17, 0, 0" x:Name="_HairStyleGrid">
                        <Button x:Name="_LeftHairStyleButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightHairStyleButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Hair Style" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Hair Color -->
                    <Grid Margin="0, 17, 0, 0" x:Name="_HairColorGrid">
                        <Button x:Name="_LeftHairColorButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightHairColorButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Hair Color" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Head -->
                    <Grid Margin="0, 17, 0, 0" x:Name="_HeadGrid">
                        <Button x:Name="_LeftHeadButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightHeadButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Head" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Torso -->
                    <Grid Margin="0, 17, 0, 0">
                        <Button x:Name="_LeftTorsoButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightTorsoButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Shirt" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Top Armor  -->
                    <Grid x:Name="_TopArmorGrid" Margin="0, 17, 0, 0">
                        <Button x:Name="_LeftTopArmorButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightTopArmorButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Top Armor" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Insignia Style  -->
                    <Grid x:Name="_InsigniaStyleGrid" Margin="0, 17, 0, 0">
                        <Button x:Name="_LeftInsigniaStyleButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightInsigniaStyleButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Insignia Style" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Insignia Color  -->
                    <Grid x:Name="_InsigniaColorGrid" Margin="0, 17, 0, 0">
                        <Button x:Name="_LeftInsigniaColorButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightInsigniaColorButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Insignia Color" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Pants -->
                    <Grid Margin="0, 17, 0, 0">
                        <Button x:Name="_LeftPantsButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightPantsButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Pants" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>


                    <!-- Bottom Armor  -->
                    <Grid x:Name="_BottomArmorGrid" Margin="0, 17, 0, 0">
                        <Button x:Name="_LeftBottomArmorButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightBottomArmorButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Bottom Armor" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>

                    <!-- Boots -->
                    <Grid x:Name="_BootsGrid" Margin="0, 17, 0, 0">
                        <Button x:Name="_LeftBootsButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Left" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="180"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Button x:Name="_RightBootsButton" Grid.Row="1" Width="45" Height="45" Padding="0" HorizontalAlignment="Right" Margin="0, 0, 0, 0">
                            <Path Stretch="Uniform" Height="30" Fill="#FFFFFFFF" Data="F1 M 78.1398,324.18L 52.5865,298.626C 51.6892,297.728 50.3385,297.459 49.1678,297.946C 47.9971,298.43 47.2305,299.574 47.2305,300.843L 60.6385,326.398L 47.2305,351.952C 47.2305,353.223 47.9971,354.364 49.1678,354.848C 49.5558,355.011 49.9638,355.09 50.3678,355.09C 51.1838,355.09 51.9852,354.77 52.5865,354.171L 78.1398,328.616C 78.7238,328.032 79.0598,327.224 79.0598,326.398C 79.0598,325.572 78.7238,324.764 78.1398,324.18 Z " RenderTransformOrigin="0.5, 0.5">
                                <Path.RenderTransform>
                                    <RotateTransform Angle="0"/>
                                </Path.RenderTransform>
                            </Path>
                        </Button>
                        <Grid HorizontalAlignment="Center">
                            <Grid Margin="10">
                                <TextBlock Text="Boots" Style="{StaticResource Heading3Primary}" TextAlignment="Center" MinWidth="70"/>
                            </Grid>
                        </Grid>
                    </Grid>
                </StackPanel>

            </StackPanel>
        </StackPanel>
    </Grid>
</UserControl>
IdentitySelectionControl.xaml (34,626 bytes)   
PlatformAny

Activities

stonstad

stonstad

2019-12-18 20:35

reporter   ~0006043

To clarify, I see this with containers having both collapsed and disabled user controls. Please let us know if you need anything at all to better test/recreate/resolve this behavior.

sfernandez

sfernandez

2019-12-19 12:20

manager   ~0006044

Last edited: 2019-12-19 12:22

I'm investigating the issue, and so far with basic examples like a stackpanel with buttons and even your xaml after commenting your BorderControl and RenderControl, if I hide elements in the xaml, gamepad navigation works as expected.
I will try to change the visibility in runtime from code like you do to see if that is the problem.

sfernandez

sfernandez

2019-12-19 12:38

manager   ~0006045

I've been able to reproduce it by changing visibility in code.
I'll let you know what I found.

stonstad

stonstad

2019-12-19 16:32

reporter   ~0006046

Thank goodness, thank you sir!

sfernandez

sfernandez

2019-12-19 17:53

manager   ~0006047

The problem was that directional navigation was not correctly discarding element sub-trees that were hidden/disabled, it was only checking the Visibility/IsEnabled on the individual controls.
Until we release the version (that should be very soon) you can workaround the bug by Collapsing the Buttons not the parent container.
Sorry for the inconvenience.

Issue History

Date Modified Username Field Change
2019-12-17 16:48 stonstad New Issue
2019-12-17 16:48 stonstad File Added: IdentitySelectionControl.cs
2019-12-17 16:48 stonstad File Added: IdentitySelectionControl.xaml
2019-12-17 17:46 sfernandez Assigned To => sfernandez
2019-12-17 17:46 sfernandez Status new => assigned
2019-12-17 17:46 sfernandez Target Version => 2.2.6
2019-12-17 17:46 sfernandez Description Updated
2019-12-18 20:35 stonstad Note Added: 0006043
2019-12-19 12:20 sfernandez Note Added: 0006044
2019-12-19 12:22 sfernandez Note Edited: 0006044
2019-12-19 12:38 sfernandez Note Added: 0006045
2019-12-19 16:32 stonstad Note Added: 0006046
2019-12-19 17:53 sfernandez Status assigned => resolved
2019-12-19 17:53 sfernandez Resolution open => fixed
2019-12-19 17:53 sfernandez Fixed in Version => 2.2.6
2019-12-19 17:53 sfernandez Note Added: 0006047
2025-10-10 13:29 jsantos Category Unity3D => Unity