public virtual void OnAfterDeserialize()
 {
     m_Main                  = SerializationHelper.DeserializeObj <ControlReferenceBinding <ButtonControl, float> >(m_SerializedMain, new object[] {});
     m_Modifiers             = SerializationHelper.Deserialize <ControlReferenceBinding <ButtonControl, float> >(m_SerializedModifiers, new object[] {});
     m_ModifierSet           = SerializationHelper.Deserialize <ControlReferenceBinding <ButtonControl, float> >(m_SerializedModifierSet, new object[] {});
     m_SerializedMain        = new SerializationHelper.JSONSerializedElement();
     m_SerializedModifiers   = null;
     m_SerializedModifierSet = null;
 }
        public override object Clone()
        {
            var clone = new ControlReferenceBinding <C, T>();

            clone.m_SourceControl = m_SourceControl;
            clone.m_ControlHash   = m_ControlHash;
            clone.m_DeviceKey     = m_DeviceKey;
            return(clone);
        }
        public override void OnGUI(Rect position, IControlDomainSource domainSource)
        {
            position.height = ControlGUIUtility.GetControlHeight(m_Main, s_MainContent);
            ControlGUIUtility.ControlField(position, m_Main, s_MainContent, domainSource, b => m_Main = b as ControlReferenceBinding <ButtonControl, float>);

            position.y     += position.height + EditorGUIUtility.standardVerticalSpacing;
            position.height = EditorGUIUtility.singleLineHeight;
            EditorGUI.BeginChangeCheck();
            int count = EditorGUI.IntField(position, s_CountContent, modifiers.Count);

            if (EditorGUI.EndChangeCheck())
            {
                if (count > modifiers.Count)
                {
                    while (modifiers.Count < count)
                    {
                        modifiers.Add(null);
                    }
                }
                else
                {
                    modifiers.RemoveRange(count, modifiers.Count - count);
                }
            }

            for (int i = 0; i < modifiers.Count; i++)
            {
                int index   = i; // See "close over the loop variable".
                var control = modifiers[i];
                position.y     += position.height + EditorGUIUtility.standardVerticalSpacing;
                position.height = ControlGUIUtility.GetControlHeight(control, s_ModifierContent);
                ControlGUIUtility.ControlField(position, control, s_ModifierContent, domainSource,
                                               b => modifiers[index] = b as ControlReferenceBinding <ButtonControl, float>);
            }

            position.y     += position.height + EditorGUIUtility.standardVerticalSpacing;
            position.height = EditorGUIUtility.singleLineHeight;
            EditorGUI.BeginChangeCheck();
            count = EditorGUI.IntField(position, s_CountContent, modifierSet.Count);
            if (EditorGUI.EndChangeCheck())
            {
                if (count > modifierSet.Count)
                {
                    while (modifierSet.Count < count)
                    {
                        modifierSet.Add(null);
                    }
                }
                else
                {
                    modifierSet.RemoveRange(count, modifierSet.Count - count);
                }
            }

            for (int i = 0; i < modifierSet.Count; i++)
            {
                int index   = i; // See "close over the loop variable".
                var control = modifierSet[i];
                position.y     += position.height + EditorGUIUtility.standardVerticalSpacing;
                position.height = ControlGUIUtility.GetControlHeight(control, s_ModifierContent);
                ControlGUIUtility.ControlField(position, control, s_ModifierContent, domainSource,
                                               b => modifierSet[index] = b as ControlReferenceBinding <ButtonControl, float>);
            }
        }
Exemple #4
0
        static GenericMenu GetMenu <C, T>(InputBinding <C, T> binding, IControlDomainSource domainSource, Action <InputBinding <C, T> > action) where C : InputControl <T>
        {
            GenericMenu menu = new GenericMenu();

            Type[]   derivedTypes = null;
            string[] derivedNames = null;
            Dictionary <Type, int> indicesOfDerivedTypes = null;

            TypeGUI.GetDerivedTypesInfo(typeof(InputBinding <C, T>), out derivedTypes, out derivedNames, out indicesOfDerivedTypes);

            Type bindingType  = typeof(ControlReferenceBinding <C, T>);
            Type existingType = binding == null ? null : binding.GetType();

            var reference = binding as ControlReferenceBinding <C, T>;

            // Add control references for devices.
            bool hasReferences = false;

            if (derivedTypes.Contains(bindingType))
            {
                hasReferences = true;
                List <DomainEntry> domainEntries = domainSource.GetDomainEntries();
                for (int i = 0; i < domainEntries.Count; i++)
                {
                    int domainHash = domainEntries[i].hash;
                    List <DomainEntry> controlEntries = domainSource.GetControlEntriesOfType(domainHash, typeof(C));

                    bool   showFlatList = (domainEntries.Count <= 1 && controlEntries.Count <= 20);
                    string prefix       = showFlatList ? string.Empty : domainEntries[i].name + "/";

                    bool nonStandardizedSectionStart = false;
                    for (int j = 0; j < controlEntries.Count; j++)
                    {
                        bool selected = (reference != null &&
                                         reference.deviceKey == domainHash &&
                                         reference.controlHash == controlEntries[j].hash);

                        if (!nonStandardizedSectionStart && !controlEntries[j].standardized)
                        {
                            nonStandardizedSectionStart = true;
                            menu.AddSeparator(prefix);
                        }

                        GUIContent name  = new GUIContent(prefix + controlEntries[j].name);
                        int        index = j; // See "close over the loop variable".
                        menu.AddItem(name, selected,
                                     () => {
                            var newReference         = new ControlReferenceBinding <C, T>();
                            newReference.deviceKey   = domainHash;
                            newReference.controlHash = controlEntries[index].hash;
                            action(newReference);
                        });
                    }
                }
            }

            if (derivedTypes.Length <= (hasReferences ? 1 : 0))
            {
                return(menu);
            }

            menu.AddSeparator("");

            // Add other control types.
            for (int i = 0; i < derivedTypes.Length; i++)
            {
                if (derivedTypes[i] != bindingType)
                {
                    bool   selected = (existingType == derivedTypes[i]);
                    string name     = NicifyBindingName(derivedNames[i]);
                    int    index    = i; // See "close over the loop variable".
                    menu.AddItem(new GUIContent(name), selected,
                                 () => {
                        var newBinding = Activator.CreateInstance(derivedTypes[index]) as InputBinding <C, T>;
                        action(newBinding);
                    });
                }
            }

            return(menu);
        }
Exemple #5
0
        public static void ControlField <C, T>(Rect position, InputBinding <C, T> binding, GUIContent label, IControlDomainSource domainSource, Action <InputBinding <C, T> > action, SerializedProperty prop = null) where C : InputControl <T>
        {
            if (prop != null)
            {
                label = EditorGUI.BeginProperty(position, label, prop);
            }

            position.height = EditorGUIUtility.singleLineHeight;

            Rect buttonPosition = EditorGUI.PrefixLabel(position, label);
            Rect detectPosition = buttonPosition;

            ControlScheme scheme           = domainSource as ControlScheme;
            bool          detectionSupport = (scheme != null);

            if (detectionSupport)
            {
                detectPosition.xMin  = detectPosition.xMax - 20;
                buttonPosition.xMax -= (20 + 4);
            }

            if (EditorGUI.DropdownButton(buttonPosition, new GUIContent(GetName(binding, domainSource) ?? "None"), FocusType.Keyboard))
            {
                GenericMenu menu = GetMenu(
                    binding, domainSource,
                    a =>
                {
                    if (prop != null)
                    {
                        Undo.RecordObjects(prop.serializedObject.targetObjects, "Control");
                    }

                    action(a);

                    if (prop != null)
                    {
                        // Flushing seems necessaary to have prefab property override status change without lag.
                        Undo.FlushUndoRecordObjects();
                        prop.serializedObject.SetIsDifferentCacheDirty();
                    }
                });
                menu.DropDown(buttonPosition);

                // GenericMenu doesn't modify GUI.changed because it relies on a callback, so let's assume that something was changed, so target object dirtying doesn't go missing
                GUI.changed = true;
            }

            if (detectionSupport)
            {
                EditorGUI.BeginDisabledGroup(s_Binding != null);
                //if (Event.current.type == EventType.repaint)
                //    EditorStyles.miniButton.Draw(detectPosition, "O", false, false, s_Binding == binding, false);
                if (GUI.Toggle(detectPosition, s_Binding == binding, "O", EditorStyles.miniButton) && s_Binding == null)
                {
                    EditorWindow window = EditorWindow.focusedWindow;
                    window.ShowNotification(new GUIContent("Waiting for input."));
                    s_BindingListener = (InputControl control) =>
                    {
                        if (!(control is C))
                        {
                            window.ShowNotification(new GUIContent("Incompatible control type."));
                            window.Repaint();
                            return(false);
                        }

                        DeviceSlot match = null;
                        Type       controlProviderType = control.provider.GetType();
                        for (int slotIndex = 0; slotIndex < scheme.deviceSlots.Count; slotIndex++)
                        {
                            Type deviceType = scheme.deviceSlots[slotIndex].type.value;
                            if (deviceType == null)
                            {
                                continue;
                            }
                            if (deviceType.IsAssignableFrom(controlProviderType))
                            {
                                match = scheme.deviceSlots[slotIndex];
                                break;
                            }
                        }
                        if (match == null)
                        {
                            window.ShowNotification(new GUIContent("Incompatible device type."));
                            window.Repaint();
                            return(false);
                        }

                        var newReference = new ControlReferenceBinding <C, T>();
                        newReference.deviceKey   = match.key;
                        newReference.controlHash = control.provider.GetHashForControlIndex(control.index);
                        action(newReference);

                        StopListening(window);

                        return(true);
                    };
                    InputSystem.ListenForBinding(s_BindingListener);
                    s_Binding = binding;

                    float time = Time.realtimeSinceStartup;
                    s_UpdateCallback = () => {
                        if (Time.realtimeSinceStartup > time + 3)
                        {
                            StopListening(window);
                        }
                    };
                    EditorApplication.update += s_UpdateCallback;
                }
                EditorGUI.EndDisabledGroup();
            }

            if (binding != null && !(binding is ControlReferenceBinding <C, T>))
            {
                EditorGUI.indentLevel++;
                position.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
                binding.OnGUI(position, domainSource);
                EditorGUI.indentLevel--;
            }

            if (prop != null)
            {
                EditorGUI.EndProperty();
            }
        }
Exemple #6
0
        public override void OnGUI(Rect position, IControlDomainSource domainSource)
        {
            // Bindings
            for (int i = 0; i < sources.Count; i++)
            {
                InputBinding <C, T> source = sources[i];
                position.height = ControlGUIUtility.GetControlHeight(source, Styles.bindingContent);
                DrawSourceSettings(position, i, domainSource);
                position.y += position.height + EditorGUIUtility.standardVerticalSpacing;
            }

            // Bindings remove and add buttons
            position.height = EditorGUIUtility.singleLineHeight;
            Rect buttonPosition = position;

            buttonPosition.width = Styles.iconToolbarMinus.image.width;
            if (GUI.Button(buttonPosition, Styles.iconToolbarMinus, GUIStyle.none))
            {
                var selected = m_Selected as InputBinding <C, T>;
                if (sources.Contains(selected))
                {
                    sources.Remove(selected);
                }
            }
            buttonPosition.x += buttonPosition.width;
            if (GUI.Button(buttonPosition, Styles.iconToolbarPlus, GUIStyle.none))
            {
                var source = new ControlReferenceBinding <C, T>();
                sources.Add(source);
                m_Selected = source;
            }
            position.y += position.height + Styles.k_Spacing;

            position.height = EditorGUIUtility.singleLineHeight;
            GUI.Label(position, "Processors");
            position.y += position.height + Styles.k_Spacing;

            // Processors
            for (int i = 0; i < processors.Count; i++)
            {
                InputBindingProcessor <C, T> processor = processors[i];
                position.height = processor.GetPropertyHeight();
                DrawProcessorSettings(position, i);
                position.y += position.height + EditorGUIUtility.standardVerticalSpacing;
            }

            // Processors remove and add buttons
            position.height      = EditorGUIUtility.singleLineHeight;
            buttonPosition       = position;
            buttonPosition.width = Styles.iconToolbarMinus.image.width;
            if (GUI.Button(buttonPosition, Styles.iconToolbarMinus, GUIStyle.none))
            {
                var selected = m_Selected as InputBindingProcessor <C, T>;
                if (selected != null && processors.Contains(selected))
                {
                    processors.Remove(selected);
                }
            }
            buttonPosition.x += buttonPosition.width;
            if (GUI.Button(buttonPosition, Styles.iconToolbarPlus, GUIStyle.none))
            {
                InputBindingProcessor <C, T> .ShowAddProcessorDropdown(buttonPosition, p => processors.Add(p));
            }
        }