Ejemplo n.º 1
0
    void DrawActionGUI()
    {
        EditorGUI.BeginChangeCheck();
        string name = EditorGUILayout.TextField("Name", selectedAction.controlData.name);

        if (EditorGUI.EndChangeCheck())
        {
            InputControlData data = selectedAction.controlData;
            data.name = name;
            selectedAction.controlData = data;
            selectedAction.name        = name;
            RefreshPropertyNames();
        }

        EditorGUI.BeginChangeCheck();
        Rect rect = EditorGUILayout.GetControlRect();
        Type type = TypeGUI.TypeField(rect, new GUIContent("Control Type"), typeof(InputControl), selectedAction.controlData.controlType);

        if (EditorGUI.EndChangeCheck())
        {
            InputControlData data = selectedAction.controlData;
            data.controlType           = type;
            selectedAction.controlData = data;
        }

        EditorGUILayout.Space();

        string[] sourceControlNames = GetSourceControlNames(selectedAction.controlData.controlType);
        if (sourceControlNames != null)
        {
            DrawCompositeControl(selectedAction, sourceControlNames);
        }
        else
        {
            if (selectedScheme >= 0 && selectedScheme < m_ActionMapEditCopy.controlSchemes.Count)
            {
                int actionIndex = m_ActionMapEditCopy.actions.IndexOf(selectedAction);
                DrawBinding(m_ActionMapEditCopy.controlSchemes[selectedScheme].bindings[actionIndex]);
            }
        }
    }
Ejemplo n.º 2
0
        public void OnGUI(Rect rect, GUIContent label, Type baseType = null, SerializedProperty prop = null)
        {
            if (prop != null)
            {
                label = EditorGUI.BeginProperty(rect, label, prop);
            }

            if (baseType == null)
            {
                baseType = typeof(InputDevice);
            }

            List <string> tagNames   = null;
            Vector2       tagMaxSize = Vector2.zero;

            if (type.value != null)
            {
                tagNames = InputDeviceUtility.GetDeviceTags(type.value);
                if (tagNames != null)
                {
                    GUIContent content = new GUIContent();
                    for (var j = 0; j < tagNames.Count; j++)
                    {
                        content.text = tagNames[j];
                        Vector2 size = EditorStyles.popup.CalcSize(content);
                        tagMaxSize = Vector2.Max(size, tagMaxSize);
                    }
                }
            }

            rect.width -= tagMaxSize.x; // Adjust width to leave room for tag
            EditorGUI.BeginChangeCheck();
            Type t = TypeGUI.TypeField(rect, label, baseType, type);

            if (EditorGUI.EndChangeCheck())
            {
                if (prop != null)
                {
                    Undo.RecordObjects(prop.serializedObject.targetObjects, "Input Device");
                }

                type = t;

                if (prop != null)
                {
                    // Flushing seems necessaary to have prefab property override status change without lag.
                    Undo.FlushUndoRecordObjects();
                    prop.serializedObject.SetIsDifferentCacheDirty();
                }
            }
            if (tagNames != null)
            {
                int oldIndent = EditorGUI.indentLevel;
                EditorGUI.indentLevel = 0;

                EditorGUI.BeginChangeCheck();
                // We want to have the ability to unset a tag after specifying one, so add an "Any" option
                var popupTags = new string[tagNames.Count + 1];
                popupTags[0] = "Any";
                tagNames.CopyTo(popupTags, 1);
                int newTagIndex = tagIndex + 1;
                rect.x     += rect.width;
                rect.width  = tagMaxSize.x;
                newTagIndex = EditorGUI.Popup(
                    rect,
                    newTagIndex,
                    popupTags);
                if (EditorGUI.EndChangeCheck())
                {
                    if (prop != null)
                    {
                        Undo.RecordObjects(prop.serializedObject.targetObjects, "Control");
                    }

                    tagIndex = newTagIndex - 1;

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

                EditorGUI.indentLevel = oldIndent;
            }
            else
            {
                // if we're no longer showing tags, reset the tag field so that we can still search on the current
                // tag selection of the device slot.
                tagIndex = -1;
            }

            if (prop != null)
            {
                EditorGUI.EndProperty();
            }
        }
Ejemplo n.º 3
0
    void DrawControlSchemeGUI()
    {
        ControlScheme scheme = m_ActionMapEditCopy.controlSchemes[selectedScheme];

        EditorGUI.BeginChangeCheck();
        string schemeName = EditorGUILayout.TextField("Control Scheme Name", scheme.name);

        if (EditorGUI.EndChangeCheck())
        {
            scheme.name = schemeName;
        }

        for (int i = 0; i < scheme.deviceSlots.Count; i++)
        {
            var deviceSlot = scheme.deviceSlots[i];

            Rect rect = EditorGUILayout.GetControlRect();
            if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition))
            {
                m_SelectedDeviceIndex = i;
                Repaint();
            }
            if (m_SelectedDeviceIndex == i)
            {
                GUI.DrawTexture(rect, EditorGUIUtility.whiteTexture);
            }

            string[] tagNames   = null;
            Vector2  tagMaxSize = Vector2.zero;
            if (deviceSlot.type != null && deviceSlot.type.value != null)
            {
                tagNames = InputDeviceUtility.GetDeviceTags(deviceSlot.type.value);
                if (tagNames != null)
                {
                    GUIContent content = new GUIContent();
                    for (var j = 0; j < tagNames.Length; j++)
                    {
                        content.text = tagNames[j];
                        Vector2 size = EditorStyles.popup.CalcSize(content);
                        tagMaxSize = Vector2.Max(size, tagMaxSize);
                    }
                }
            }

            rect.width -= tagMaxSize.x; // Adjust width to leave room for tag
            EditorGUI.BeginChangeCheck();
            Type t = TypeGUI.TypeField(rect, new GUIContent("Device Type"), typeof(InputDevice), deviceSlot.type);
            if (EditorGUI.EndChangeCheck())
            {
                deviceSlot.type = t;
            }
            if (tagNames != null)
            {
                EditorGUI.BeginChangeCheck();
                // We want to have the ability to unset a tag after specifying one, so add an "Any" option
                var popupTags = new string[tagNames.Length + 1];
                popupTags[0] = "Any";
                tagNames.CopyTo(popupTags, 1);
                int tagIndex = deviceSlot.tagIndex + 1;
                rect.x    += rect.width;
                rect.width = tagMaxSize.x;
                tagIndex   = EditorGUI.Popup(
                    rect,
                    tagIndex,
                    popupTags);
                if (EditorGUI.EndChangeCheck())
                {
                    deviceSlot.tagIndex = tagIndex - 1;
                }
            }
        }

        // Device remove and add buttons
        EditorGUILayout.BeginHorizontal();
        {
            GUILayout.Space(15 * EditorGUI.indentLevel);

            if (GUILayout.Button(Styles.iconToolbarMinus, GUIStyle.none))
            {
                RemoveDevice();
            }

            if (GUILayout.Button(Styles.iconToolbarPlus, GUIStyle.none))
            {
                AddDevice();
            }

            GUILayout.FlexibleSpace();
        }
        EditorGUILayout.EndHorizontal();

        // Pad this area with spacing so all control schemes use same heights,
        // and the actions table below doesn't move when switching control scheme.
        int maxDevices = 0;

        for (int i = 0; i < m_ActionMapEditCopy.controlSchemes.Count; i++)
        {
            maxDevices = Mathf.Max(maxDevices, m_ActionMapEditCopy.controlSchemes[i].deviceSlots.Count);
        }
        int extraLines = maxDevices - scheme.deviceSlots.Count;

        EditorGUILayout.GetControlRect(true, extraLines * (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing));
    }
Ejemplo n.º 4
0
    void DrawActionGUI()
    {
        EditorGUI.BeginChangeCheck();
        string name = EditorGUILayout.TextField("Name", selectedAction.name);

        if (EditorGUI.EndChangeCheck())
        {
            selectedAction.name = name;
            RefreshPropertyNames();
        }

        EditorGUI.BeginChangeCheck();
        Rect rect = EditorGUILayout.GetControlRect();
        Type type = TypeGUI.TypeField(rect, new GUIContent("Control Type"), typeof(InputControl), selectedAction.controlType);

        if (EditorGUI.EndChangeCheck())
        {
            int  actionIndex = m_ActionMapEditCopy.actions.IndexOf(selectedAction);
            bool anyBindings = false;
            for (int i = 0; i < m_ActionMapEditCopy.controlSchemes.Count; i++)
            {
                var scheme = m_ActionMapEditCopy.controlSchemes[i];
                if (scheme.bindings[actionIndex] != null)
                {
                    anyBindings = true;
                    break;
                }
            }
            bool proceed = true;
            if (anyBindings)
            {
                proceed = EditorUtility.DisplayDialog(
                    "Change Action Control Type",
                    "Changing the Control Type will clear all bindings for this action ('" + selectedAction.name + "').",
                    "Change",
                    "Cancel");
            }
            if (proceed)
            {
                selectedAction.controlType = type;
                m_ActionMapEditCopy.EnforceBindingsTypeConsistency();
            }
        }

        EditorGUI.BeginChangeCheck();
        rect = EditorGUILayout.GetControlRect();
        bool combined = EditorGUI.Toggle(rect, new GUIContent("Combined"), selectedAction.combined);

        if (EditorGUI.EndChangeCheck())
        {
            int  actionIndex = m_ActionMapEditCopy.actions.IndexOf(selectedAction);
            bool anyBindings = false;
            for (int i = 0; i < m_ActionMapEditCopy.controlSchemes.Count; i++)
            {
                var scheme = m_ActionMapEditCopy.controlSchemes[i];
                if (scheme.bindings[actionIndex] != null)
                {
                    anyBindings = true;
                    break;
                }
            }
            bool proceed = true;
            if (anyBindings)
            {
                proceed = EditorUtility.DisplayDialog(
                    "Change Action",
                    "Changing whether the Action is combined will clear all bindings for this action ('" + selectedAction.name + "').",
                    "Change",
                    "Cancel");
            }
            if (proceed)
            {
                selectedAction.combined = combined;
                m_ActionMapEditCopy.EnforceBindingsTypeConsistency();
            }
        }

        if (selectedAction.combined)
        {
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Actions being combined");
            EditorGUILayout.Space();

            InputBinding binding = selectedAction.selfBinding;
            float        height  = binding.GetPropertyHeight();
            rect = EditorGUILayout.GetControlRect(true, height);
            binding.OnGUI(rect, m_ActionMapEditCopy);
        }
        else
        {
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Bindings for " + m_ActionMapEditCopy.controlSchemes[selectedScheme].name);
            EditorGUILayout.Space();

            if (selectedScheme >= 0 && selectedScheme < m_ActionMapEditCopy.controlSchemes.Count)
            {
                int          actionIndex = m_ActionMapEditCopy.actions.IndexOf(selectedAction);
                InputBinding binding     = m_ActionMapEditCopy.controlSchemes[selectedScheme].bindings[actionIndex];
                if (binding != null)
                {
                    float height = binding.GetPropertyHeight();
                    rect = EditorGUILayout.GetControlRect(true, height);
                    binding.OnGUI(rect, m_ActionMapEditCopy.controlSchemes[m_SelectedScheme]);
                }
            }
        }
    }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
0
    void DrawControlSchemeGUI()
    {
        ControlScheme scheme = m_ActionMapEditCopy.controlSchemes[selectedScheme];

        EditorGUI.BeginChangeCheck();
        string schemeName = EditorGUILayout.TextField("Control Scheme Name", scheme.name);

        if (EditorGUI.EndChangeCheck())
        {
            scheme.name = schemeName;
        }

        for (int i = 0; i < scheme.serializableDeviceTypes.Count; i++)
        {
            Rect rect = EditorGUILayout.GetControlRect();

            if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition))
            {
                m_SelectedDeviceIndex = i;
                Repaint();
            }
            if (m_SelectedDeviceIndex == i)
            {
                GUI.DrawTexture(rect, EditorGUIUtility.whiteTexture);
            }

            EditorGUI.BeginChangeCheck();
            Type t = TypeGUI.TypeField(rect, new GUIContent("Device Type"), typeof(InputDevice), scheme.serializableDeviceTypes[i]);
            if (EditorGUI.EndChangeCheck())
            {
                scheme.serializableDeviceTypes[i].value = t;
            }
        }

        // Device remove and add buttons
        EditorGUILayout.BeginHorizontal();
        {
            GUILayout.Space(15 * EditorGUI.indentLevel);

            if (GUILayout.Button(Styles.iconToolbarMinus, GUIStyle.none))
            {
                RemoveDevice();
            }

            if (GUILayout.Button(Styles.iconToolbarPlus, GUIStyle.none))
            {
                AddDevice();
            }

            GUILayout.FlexibleSpace();
        }
        EditorGUILayout.EndHorizontal();

        // Pad this area with spacing so all control schemes use same heights,
        // and the actions table below doesn't move when switching control scheme.
        int maxDevices = 0;

        for (int i = 0; i < m_ActionMapEditCopy.controlSchemes.Count; i++)
        {
            maxDevices = Mathf.Max(maxDevices, m_ActionMapEditCopy.controlSchemes[i].serializableDeviceTypes.Count);
        }
        int extraLines = maxDevices - scheme.serializableDeviceTypes.Count;

        EditorGUILayout.GetControlRect(true, extraLines * (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing));
    }