private void RenderControllerList()

in Assets/MixedRealityToolkit/Inspectors/Profiles/MixedRealityControllerMappingProfileInspector.cs [123:329]


        private void RenderControllerList(SerializedProperty controllerList)
        {
            if (thisProfile.MixedRealityControllerMappingProfiles.Length != controllerList.arraySize) { return; }

            EditorGUILayout.Space();

            if (GUILayout.Button(ControllerAddButtonContent, EditorStyles.miniButton))
            {
                AddController(controllerList, typeof(GenericJoystickController));
                return;
            }

            controllerRenderList.Clear();

            GUILayout.Space(12f);

            using (var outerVerticalScope = new GUILayout.VerticalScope())
            {
                GUILayout.HorizontalScope horizontalScope = null;

                for (int i = 0; i < thisProfile.MixedRealityControllerMappingProfiles.Length; i++)
                {
                    MixedRealityControllerMapping controllerMapping = thisProfile.MixedRealityControllerMappingProfiles[i];
                    Type controllerType = controllerMapping.ControllerType;
                    if (controllerType == null) { continue; }

                    Handedness handedness = controllerMapping.Handedness;
                    bool useCustomInteractionMappings = controllerMapping.HasCustomInteractionMappings;
                    SupportedControllerType supportedControllerType = controllerMapping.SupportedControllerType;

                    var controllerMappingProperty = controllerList.GetArrayElementAtIndex(i);
                    var handednessProperty = controllerMappingProperty.FindPropertyRelative("handedness");

                    if (!useCustomInteractionMappings)
                    {
                        bool skip = false;

                        // Merge controllers with the same supported controller type.
                        for (int j = 0; j < controllerRenderList.Count; j++)
                        {
                            if (controllerRenderList[j].SupportedControllerType == supportedControllerType &&
                                controllerRenderList[j].Handedness == handedness)
                            {
                                try
                                {
                                    thisProfile.MixedRealityControllerMappingProfiles[i].SynchronizeInputActions(controllerRenderList[j].Interactions);
                                }
                                catch (ArgumentException e)
                                {
                                    Debug.LogError($"Controller mappings between {thisProfile.MixedRealityControllerMappingProfiles[i].Description} and {controllerMapping.Description} do not match. Error message: {e.Message}");
                                }
                                serializedObject.ApplyModifiedProperties();
                                skip = true;
                            }
                        }

                        if (skip) { continue; }
                    }

                    controllerRenderList.Add(new ControllerRenderProfile(supportedControllerType, handedness, thisProfile.MixedRealityControllerMappingProfiles[i].Interactions));

                    string controllerTitle = thisProfile.MixedRealityControllerMappingProfiles[i].Description;
                    var interactionsProperty = controllerMappingProperty.FindPropertyRelative("interactions");

                    if (useCustomInteractionMappings)
                    {
                        if (horizontalScope != null) { horizontalScope.Dispose(); horizontalScope = null; }

                        GUILayout.Space(24f);

                        using (var verticalScope = new GUILayout.VerticalScope())
                        {
                            using (horizontalScope = new GUILayout.HorizontalScope())
                            {
                                EditorGUIUtility.labelWidth = 64f;
                                EditorGUIUtility.fieldWidth = 64f;
                                EditorGUILayout.LabelField(controllerTitle);
                                EditorGUIUtility.fieldWidth = defaultFieldWidth;
                                EditorGUIUtility.labelWidth = defaultLabelWidth;

                                if (GUILayout.Button(ControllerMinusButtonContent, EditorStyles.miniButtonRight, GUILayout.Width(24f)))
                                {
                                    controllerList.DeleteArrayElementAtIndex(i);
                                    return;
                                }
                            }
                            EditorGUI.indentLevel++;

                            EditorGUIUtility.labelWidth = 128f;
                            EditorGUIUtility.fieldWidth = 64f;

                            EditorGUI.BeginChangeCheck();

                            // Generic Type dropdown
                            Type[] genericTypes = MixedRealityControllerMappingProfile.CustomControllerMappingTypes;
                            var genericTypeListContent = new GUIContent[genericTypes.Length];
                            var genericTypeListIds = new int[genericTypes.Length];
                            int currentGenericType = -1;
                            for (int genericTypeIdx = 0; genericTypeIdx < genericTypes.Length; genericTypeIdx++)
                            {
                                var attribute = MixedRealityControllerAttribute.Find(genericTypes[genericTypeIdx]);
                                if (attribute != null)
                                {
                                    genericTypeListContent[genericTypeIdx] = new GUIContent(attribute.SupportedControllerType.ToString().Replace("Generic", "").ToProperCase() + " Controller");
                                }
                                else
                                {
                                    genericTypeListContent[genericTypeIdx] = new GUIContent("Unknown Controller");
                                }

                                genericTypeListIds[genericTypeIdx] = genericTypeIdx;

                                if (controllerType == genericTypes[genericTypeIdx])
                                {
                                    currentGenericType = genericTypeIdx;
                                }
                            }
                            Debug.Assert(currentGenericType != -1);

                            currentGenericType = EditorGUILayout.IntPopup(GenericTypeContent, currentGenericType, genericTypeListContent, genericTypeListIds);
                            controllerType = genericTypes[currentGenericType];

                            {
                                // Handedness dropdown
                                var attribute = MixedRealityControllerAttribute.Find(controllerType);
                                if (attribute != null && attribute.SupportedHandedness.Length >= 1)
                                {
                                    // Make sure handedness is valid for the selected controller type.
                                    if (Array.IndexOf(attribute.SupportedHandedness, (Handedness)handednessProperty.intValue) < 0)
                                    {
                                        handednessProperty.intValue = (int)attribute.SupportedHandedness[0];
                                    }

                                    if (attribute.SupportedHandedness.Length >= 2)
                                    {
                                        var handednessListContent = new GUIContent[attribute.SupportedHandedness.Length];
                                        var handednessListIds = new int[attribute.SupportedHandedness.Length];
                                        for (int handednessIdx = 0; handednessIdx < attribute.SupportedHandedness.Length; handednessIdx++)
                                        {
                                            handednessListContent[handednessIdx] = new GUIContent(attribute.SupportedHandedness[handednessIdx].ToString());
                                            handednessListIds[handednessIdx] = (int)attribute.SupportedHandedness[handednessIdx];
                                        }

                                        handednessProperty.intValue = EditorGUILayout.IntPopup(HandednessTypeContent, handednessProperty.intValue, handednessListContent, handednessListIds);
                                    }
                                }
                                else
                                {
                                    handednessProperty.intValue = (int)Handedness.None;
                                }
                            }

                            if (EditorGUI.EndChangeCheck())
                            {
                                interactionsProperty.ClearArray();
                                serializedObject.ApplyModifiedProperties();
                                thisProfile.MixedRealityControllerMappingProfiles[i].ControllerType.Type = genericTypes[currentGenericType];
                                thisProfile.MixedRealityControllerMappingProfiles[i].SetDefaultInteractionMapping(true);
                                serializedObject.ApplyModifiedProperties();
                                return;
                            }

                            EditorGUIUtility.labelWidth = defaultLabelWidth;
                            EditorGUIUtility.fieldWidth = defaultFieldWidth;

                            EditorGUI.indentLevel--;

                            if (GUILayout.Button("Edit Input Action Map"))
                            {
                                ControllerPopupWindow.Show(controllerMapping, interactionsProperty, handedness);
                            }

                            if (GUILayout.Button("Reset Input Actions"))
                            {
                                interactionsProperty.ClearArray();
                                serializedObject.ApplyModifiedProperties();
                                thisProfile.MixedRealityControllerMappingProfiles[i].SetDefaultInteractionMapping(true);
                                serializedObject.ApplyModifiedProperties();
                            }
                        }
                    }
                    else
                    {
                        if (supportedControllerType == SupportedControllerType.WindowsMixedReality &&
                            handedness == Handedness.None)
                        {
                            controllerTitle = "HoloLens Voice and Clicker";
                        }

                        if (handedness != Handedness.Right)
                        {
                            if (horizontalScope != null) { horizontalScope.Dispose(); horizontalScope = null; }
                            horizontalScope = new GUILayout.HorizontalScope();
                        }

                        var buttonContent = new GUIContent(controllerTitle, ControllerMappingLibrary.GetControllerTextureScaled(controllerType, handedness));

                        if (GUILayout.Button(buttonContent, controllerButtonStyle, GUILayout.Height(128f), GUILayout.MinWidth(32f), GUILayout.ExpandWidth(true)))
                        {
                            ControllerPopupWindow.Show(controllerMapping, interactionsProperty, handedness);
                        }
                    }
                }

                if (horizontalScope != null) { horizontalScope.Dispose(); horizontalScope = null; }
            }
        }