Exemplo n.º 1
0
        static void StopListening(EditorWindow window)
        {
            EditorApplication.update -= s_UpdateCallback;
            InputSystem.ListenForBinding(s_BindingListener, false);

            s_BindingListener = null;
            s_Binding         = null;
            s_UpdateCallback  = null;

            window.RemoveNotification();
            window.Repaint();
        }
Exemplo n.º 2
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();
            }
        }