private void OnCompositeParametersModified()
        {
            Debug.Assert(m_CompositeParameters != null);

            var path = m_PathProperty.stringValue;
            var nameAndParameters = InputControlLayout.ParseNameAndParameters(path);

            nameAndParameters.parameters = m_CompositeParameters.GetParameters();

            m_PathProperty.stringValue = nameAndParameters.ToString();

            OnPathModified();
        }
예제 #2
0
        private void InitializeCompositeProperties()
        {
            // Find name of current composite.
            var path = m_PathProperty.stringValue;
            var compositeNameAndParameters = InputControlLayout.ParseNameAndParameters(path);
            var compositeName = compositeNameAndParameters.name;
            var compositeType = InputBindingComposite.s_Composites.LookupTypeRegistration(compositeName);

            // Collect all possible composite types.
            var selectedCompositeIndex   = -1;
            var compositeTypeOptionsList = new List <GUIContent>();
            var compositeTypeList        = new List <string>();
            var currentIndex             = 0;

            foreach (var composite in InputBindingComposite.s_Composites.internedNames.Where(x =>
                                                                                             !InputBindingComposite.s_Composites.aliases.Contains(x)).OrderBy(x => x))
            {
                if (InputBindingComposite.s_Composites.LookupTypeRegistration(composite) == compositeType)
                {
                    selectedCompositeIndex = currentIndex;
                }
                var name = ObjectNames.NicifyVariableName(composite);
                compositeTypeOptionsList.Add(new GUIContent(name));
                compositeTypeList.Add(composite);
                ++currentIndex;
            }

            // If the current composite type isn't a registered type, add it to the list as
            // an extra option.
            if (selectedCompositeIndex == -1)
            {
                selectedCompositeIndex = compositeTypeList.Count;
                compositeTypeOptionsList.Add(new GUIContent(ObjectNames.NicifyVariableName(compositeName)));
                compositeTypeList.Add(compositeName);
            }

            m_CompositeTypes        = compositeTypeList.ToArray();
            m_CompositeTypeOptions  = compositeTypeOptionsList.ToArray();
            m_SelectedCompositeType = selectedCompositeIndex;

            // Initialize parameters.
            m_CompositeParameters = new ParameterListView
            {
                onChange = OnCompositeParametersModified
            };
            if (compositeType != null)
            {
                m_CompositeParameters.Initialize(compositeType, compositeNameAndParameters.parameters);
            }
        }
예제 #3
0
        private void InitializeCompositePartProperties()
        {
            var currentCompositePart = m_BindingProperty.FindPropertyRelative("m_Name").stringValue;

            ////REVIEW: this makes a lot of assumptions about the serialized data based on the one property we've been given in the ctor
            // Determine the name of the current composite type that the part belongs to.
            var bindingArrayProperty  = m_BindingProperty.GetArrayPropertyFromElement();
            var partBindingIndex      = InputActionSerializationHelpers.GetIndex(bindingArrayProperty, m_BindingProperty);
            var compositeBindingIndex =
                InputActionSerializationHelpers.GetCompositeStartIndex(bindingArrayProperty, partBindingIndex);

            if (compositeBindingIndex == -1)
            {
                return;
            }
            var compositeBindingProperty   = bindingArrayProperty.GetArrayElementAtIndex(compositeBindingIndex);
            var compositePath              = compositeBindingProperty.FindPropertyRelative("m_Path").stringValue;
            var compositeNameAndParameters = InputControlLayout.ParseNameAndParameters(compositePath);

            // Initialize option list from all parts available for the composite.
            var optionList            = new List <GUIContent>();
            var nameList              = new List <string>();
            var currentIndex          = 0;
            var selectedPartNameIndex = -1;

            foreach (var partName in InputBindingComposite.GetPartNames(compositeNameAndParameters.name))
            {
                if (partName.Equals(currentCompositePart, StringComparison.InvariantCultureIgnoreCase))
                {
                    selectedPartNameIndex = currentIndex;
                }
                var niceName = ObjectNames.NicifyVariableName(partName);
                optionList.Add(new GUIContent(niceName));
                nameList.Add(partName);
                ++currentIndex;
            }

            // If currently selected part is not in list, add it as an option.
            if (selectedPartNameIndex == -1)
            {
                selectedPartNameIndex = nameList.Count;
                optionList.Add(new GUIContent(ObjectNames.NicifyVariableName(currentCompositePart)));
                nameList.Add(currentCompositePart);
            }

            m_CompositeParts        = nameList.ToArray();
            m_CompositePartOptions  = optionList.ToArray();
            m_SelectedCompositePart = selectedPartNameIndex;
        }
        private void InitializeCompositeParameters()
        {
            m_CompositeParameters = new ParameterListView
            {
                onChange = OnCompositeParametersModified
            };

            var path = m_PathProperty.stringValue;
            var nameAndParameters = InputControlLayout.ParseNameAndParameters(path);

            var compositeType = InputBindingComposite.s_Composites.LookupTypeRegistration(nameAndParameters.name);

            if (compositeType != null)
            {
                m_CompositeParameters.Initialize(compositeType, nameAndParameters.parameters);
            }
        }
예제 #5
0
        private static object InstantiateBindingComposite(string nameAndParameters)
        {
            var nameAndParametersParsed = InputControlLayout.ParseNameAndParameters(nameAndParameters);

            // Look up.
            var type = InputBindingComposite.s_Composites.LookupTypeRegistration(nameAndParametersParsed.name);

            if (type == null)
            {
                throw new Exception(string.Format("No binding composite with name '{0}' has been registered",
                                                  nameAndParametersParsed.name));
            }

            // Instantiate.
            var instance = Activator.CreateInstance(type);

            ////REVIEW: typecheck for IInputBindingComposite? (at least in dev builds)

            // Set parameters.
            InputDeviceBuilder.SetParameters(instance, nameAndParametersParsed.parameters);

            return(instance);
        }
        public static SerializedProperty ChangeCompositeBindingType(SerializedProperty bindingProperty,
                                                                    InputControlLayout.NameAndParameters nameAndParameters)
        {
            var bindingsArrayProperty = bindingProperty.GetArrayPropertyFromElement();

            Debug.Assert(bindingsArrayProperty != null, "SerializedProperty is not an array of bindings");
            var bindingIndex = bindingProperty.GetIndexOfArrayElement();

            Debug.Assert(IsCompositeBinding(bindingProperty),
                         $"Binding {bindingProperty.propertyPath} is not a composite");

            // If the composite still has the default name, change it to the default
            // one for the new composite type.
            var pathProperty = bindingProperty.FindPropertyRelative("m_Path");
            var nameProperty = bindingProperty.FindPropertyRelative("m_Name");

            if (nameProperty.stringValue ==
                ObjectNames.NicifyVariableName(InputControlLayout.ParseNameAndParameters(pathProperty.stringValue).name))
            {
                nameProperty.stringValue = ObjectNames.NicifyVariableName(nameAndParameters.name);
            }

            pathProperty.stringValue = nameAndParameters.ToString();

            // Adjust part bindings if we have information on the registered composite. If we don't have
            // a type, we don't know about the parts. In that case, leave part bindings untouched.
            var compositeType = InputBindingComposite.s_Composites.LookupTypeRegistration(nameAndParameters.name);

            if (compositeType != null)
            {
                var actionName = bindingProperty.FindPropertyRelative("m_Action").stringValue;

                // Repurpose existing part bindings for the new composite or add any part bindings that
                // we're missing.
                var fields    = compositeType.GetFields(BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance);
                var partIndex = 0;
                var partBindingsStartIndex = bindingIndex + 1;
                foreach (var field in fields)
                {
                    // Skip fields that aren't marked with [InputControl] attribute.
                    if (field.GetCustomAttribute <InputControlAttribute>(false) == null)
                    {
                        continue;
                    }

                    // See if we can reuse an existing part binding.
                    SerializedProperty partProperty = null;
                    if (partBindingsStartIndex + partIndex < bindingsArrayProperty.arraySize)
                    {
                        ////REVIEW: this should probably look up part bindings by name rather than going sequentially
                        var element = bindingsArrayProperty.GetArrayElementAtIndex(partBindingsStartIndex + partIndex);
                        if (((InputBinding.Flags)element.FindPropertyRelative("m_Flags").intValue & InputBinding.Flags.PartOfComposite) != 0)
                        {
                            partProperty = element;
                        }
                    }

                    // If not, insert a new binding.
                    if (partProperty == null)
                    {
                        partProperty = AddBindingToBindingArray(bindingsArrayProperty, partBindingsStartIndex + partIndex,
                                                                flags: InputBinding.Flags.PartOfComposite);
                    }

                    // Initialize.
                    partProperty.FindPropertyRelative("m_Name").stringValue   = ObjectNames.NicifyVariableName(field.Name);
                    partProperty.FindPropertyRelative("m_Action").stringValue = actionName;
                    ++partIndex;
                }

                ////REVIEW: when we allow adding the same part multiple times, we may want to do something smarter here
                // Delete extraneous part bindings.
                while (partBindingsStartIndex + partIndex < bindingsArrayProperty.arraySize)
                {
                    var element = bindingsArrayProperty.GetArrayElementAtIndex(partBindingsStartIndex + partIndex);
                    if (((InputBinding.Flags)element.FindPropertyRelative("m_Flags").intValue & InputBinding.Flags.PartOfComposite) == 0)
                    {
                        break;
                    }

                    bindingsArrayProperty.DeleteArrayElementAtIndex(partBindingsStartIndex + partIndex);
                    // No incrementing of partIndex.
                }
            }

            return(bindingProperty);
        }