private void RefreshBindings()
        {
            // Gather a mapping of device types to list of bindings that use the given type.
            var perDeviceTypeUsedControlIndices = new Dictionary <int, List <int> >();

            controlScheme.ExtractDeviceTypesAndControlHashes(perDeviceTypeUsedControlIndices);

            for (int slotIndex = 0; slotIndex < controlScheme.deviceSlots.Count; slotIndex++)
            {
                DeviceSlot slot  = controlScheme.deviceSlots[slotIndex];
                InputState state = deviceStates[slotIndex];
                List <int> hashes;
                if (perDeviceTypeUsedControlIndices.TryGetValue(slot.key, out hashes))
                {
                    var indices = new List <int>(hashes.Count);
                    for (int i = 0; i < hashes.Count; i++)
                    {
                        indices.Add(state.controlProvider.GetControlIndexFromHash(hashes[i]));
                    }
                    state.SetUsedControls(indices);
                    (state.controlProvider as InputDevice).PostProcessEnabledControls(state);
                }
                else
                {
                    state.SetAllControlsEnabled(false);
                }
            }
        }
        public object Clone()
        {
            var clone = new DeviceSlot();

            clone.m_Key      = m_Key;
            clone.m_TagIndex = m_TagIndex;
            clone.m_Type     = m_Type;
            clone.m_SortedCachedUsedControlHashes = new List <int>(m_SortedCachedUsedControlHashes);

            return(clone);
        }
示例#3
0
        public List <DomainEntry> GetDomainEntries()
        {
            var entries = new List <DomainEntry>(deviceSlots.Count);

            for (int i = 0; i < deviceSlots.Count; i++)
            {
                DeviceSlot slot = deviceSlots[i];
                if (slot == null)
                {
                    entries.Add(new DomainEntry()
                    {
                        name = string.Empty, hash = -1
                    });
                }
                else
                {
                    entries.Add(new DomainEntry()
                    {
                        name = slot.ToString(), hash = slot.key
                    });
                }
            }
            return(entries);
        }
示例#4
0
        public List <DomainEntry> GetControlEntriesOfType(int domainId, Type controlType)
        {
            DeviceSlot slot = GetDeviceSlot(domainId);

            return(InputDeviceUtility.GetDeviceControlEntriesOfType(slot == null ? null : slot.type, controlType));
        }
示例#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();
            }
        }