Exemplo n.º 1
0
            private void AddControlLayouts(TreeViewItem parent, ref int id)
            {
                // Split root into three different groups:
                // 1) Control layouts
                // 2) Device layouts that don't match specific products
                // 3) Device layouts that match specific products

                var controls = AddChild(parent, "Controls", ref id);
                var devices  = AddChild(parent, "Abstract Devices", ref id);
                var products = AddChild(parent, "Specific Devices", ref id);

                foreach (var layout in EditorInputControlLayoutCache.allControlLayouts)
                {
                    AddControlLayoutItem(layout, controls, ref id);
                }
                foreach (var layout in EditorInputControlLayoutCache.allDeviceLayouts)
                {
                    AddControlLayoutItem(layout, devices, ref id);
                }
                foreach (var layout in EditorInputControlLayoutCache.allProductLayouts)
                {
                    var rootBaseLayoutName = InputControlLayout.s_Layouts.GetRootLayoutName(layout.name).ToString();
                    var groupName          = string.IsNullOrEmpty(rootBaseLayoutName) ? "Other" : rootBaseLayoutName + "s";

                    var group = products.children?.FirstOrDefault(x => x.displayName == groupName);
                    if (group == null)
                    {
                        group = AddChild(products, groupName, ref id);
                        if (!string.IsNullOrEmpty(rootBaseLayoutName))
                        {
                            group.icon = EditorInputControlLayoutCache.GetIconForLayout(rootBaseLayoutName);
                        }
                    }

                    AddControlLayoutItem(layout, group, ref id);
                }

                controls.children?.Sort((a, b) => string.Compare(a.displayName, b.displayName));
                devices.children?.Sort((a, b) => string.Compare(a.displayName, b.displayName));

                if (products.children != null)
                {
                    products.children.Sort((a, b) => string.Compare(a.displayName, b.displayName));
                    foreach (var productGroup in products.children)
                    {
                        productGroup.children.Sort((a, b) => string.Compare(a.displayName, b.displayName));
                    }
                }
            }
Exemplo n.º 2
0
        private static string DeviceRequirementToDisplayString(InputControlScheme.DeviceRequirement requirement)
        {
            ////TODO: need something more flexible to produce correct results for more than the simple string we produce here
            var deviceLayout     = InputControlPath.TryGetDeviceLayout(requirement.controlPath);
            var deviceLayoutText = !string.IsNullOrEmpty(deviceLayout)
                ? EditorInputControlLayoutCache.GetDisplayName(deviceLayout)
                : string.Empty;
            var usages = InputControlPath.TryGetDeviceUsages(requirement.controlPath);

            if (usages != null && usages.Length > 0)
            {
                return($"{deviceLayoutText} {string.Join("}{", usages)}");
            }

            return(deviceLayoutText);
        }
Exemplo n.º 3
0
        private void AddControlTreeItemsRecursive(InputControlLayout layout, DeviceDropdownItem parent,
                                                  string device, string usage, bool searchable, ControlDropdownItem parentControl = null)
        {
            foreach (var control in layout.controls.OrderBy(a => a.name))
            {
                if (control.isModifyingChildControlByPath)
                {
                    continue;
                }

                // Skip variants except the default variant and variants dictated by the layout itself.
                if (!control.variants.IsEmpty() && control.variants != InputControlLayout.DefaultVariant &&
                    (layout.variants.IsEmpty() || !InputControlLayout.VariantsMatch(layout.variants, control.variants)))
                {
                    continue;
                }

                AddControlItem(parent, parentControl, control, device, usage, searchable);
            }

            // Add optional controls for devices.
            var optionalControls = EditorInputControlLayoutCache.GetOptionalControlsForLayout(layout.name);

            if (optionalControls.Any() && layout.isDeviceLayout)
            {
                var optionalGroup = new AdvancedDropdownItem("Optional Controls");
                foreach (var optionalControl in optionalControls)
                {
                    ////FIXME: this should list children, too
                    ////FIXME: this should handle arrays, too
                    if (LayoutMatchesExpectedControlLayoutFilter(optionalControl.layout))
                    {
                        var child = new OptionalControlDropdownItem(optionalControl, device, usage);
                        child.icon = EditorInputControlLayoutCache.GetIconForLayout(optionalControl.layout);
                        optionalGroup.AddChild(child);
                    }
                }

                if (optionalGroup.children.Any())
                {
                    var deviceName = EditorInputControlLayoutCache.TryGetLayout(device).m_DisplayName ??
                                     ObjectNames.NicifyVariableName(device);
                    parent.AddSeparator("Controls Present on More Specific " + deviceName.GetPlural());
                    parent.AddChild(optionalGroup);
                }
            }
        }
Exemplo n.º 4
0
            private void AddUser(TreeViewItem parent, InputUser user, ref int id)
            {
                ////REVIEW: can we get better identification? allow associating GameObject with user?
                var userItem = AddChild(parent, "User #" + user.index, ref id);

                // Control scheme.
                var controlScheme = user.controlScheme;

                if (controlScheme != null)
                {
                    AddChild(userItem, "Control Scheme: " + controlScheme, ref id);
                }

                // Paired devices.
                var pairedDevices = user.pairedDevices;

                if (pairedDevices.Count > 0)
                {
                    var devicesItem = AddChild(userItem, "Paired Devices", ref id);
                    foreach (var device in user.pairedDevices)
                    {
                        var item = new DeviceItem
                        {
                            id          = id++,
                            depth       = devicesItem.depth + 1,
                            displayName = device.ToString(),
                            device      = device,
                            icon        = EditorInputControlLayoutCache.GetIconForLayout(device.layout),
                        };
                        devicesItem.AddChild(item);
                    }
                }

                // Actions.
                var actions = user.actions;

                if (actions != null)
                {
                    var actionsItem = AddChild(userItem, "Actions", ref id);
                    foreach (var action in actions)
                    {
                        AddActionItem(actionsItem, action, ref id);
                    }

                    parent.children?.Sort((a, b) => string.Compare(a.displayName, b.displayName, StringComparison.CurrentCultureIgnoreCase));
                }
            }
Exemplo n.º 5
0
        // This differs from RebindingOperation.GeneratePathForControl in that it cycles through all
        // layouts in the inheritance chain and generates a path for each one that contains the given control.
        private static IEnumerable <string> GeneratePossiblePathsForControl(InputControl control)
        {
            var builder          = new StringBuilder();
            var deviceLayoutName = control.device.m_Layout;

            do
            {
                // Skip layout if it is supposed to be hidden in the UI.
                var layout = EditorInputControlLayoutCache.TryGetLayout(deviceLayoutName);
                if (layout.hideInUI)
                {
                    continue;
                }

                builder.Length = 0;
                yield return(control.BuildPath(deviceLayoutName, builder));
            }while (InputControlLayout.s_Layouts.baseLayoutTable.TryGetValue(deviceLayoutName, out deviceLayoutName));
        }
Exemplo n.º 6
0
            private void AddDevices(TreeViewItem parent, IEnumerable <InputDevice> devices, ref int id, int participantId = InputDevice.kLocalParticipantId)
            {
                foreach (var device in devices)
                {
                    if (device.m_ParticipantId != participantId)
                    {
                        continue;
                    }

                    var item = new DeviceItem
                    {
                        id          = id++,
                        depth       = parent.depth + 1,
                        displayName = device.name,
                        device      = device,
                        icon        = EditorInputControlLayoutCache.GetIconForLayout(device.layout),
                    };
                    parent.AddChild(item);
                }

                parent.children?.Sort((a, b) => string.Compare(a.displayName, b.displayName));
            }
Exemplo n.º 7
0
        internal void AddControlItem(IInputControlPickerLayout controlPickerLayout,
                                     DeviceDropdownItem parent, ControlDropdownItem parentControl,
                                     InputControlLayout.ControlItem control, string device, string usage, bool searchable,
                                     string controlNameOverride = default)
        {
            var controlName = controlNameOverride ?? control.name;

            // If it's an array, generate a control entry for each array element.
            for (var i = 0; i < (control.isArray ? control.arraySize : 1); ++i)
            {
                var name        = control.isArray ? controlName + i : controlName;
                var displayName = !string.IsNullOrEmpty(control.displayName)
                    ? (control.isArray ? $"{control.displayName} #{i}" : control.displayName)
                    : name;

                var child = new ControlDropdownItem(parentControl, name, displayName,
                                                    device, usage, searchable);
                child.icon = EditorInputControlLayoutCache.GetIconForLayout(control.layout);
                var controlLayout = EditorInputControlLayoutCache.TryGetLayout(control.layout);

                if (LayoutMatchesExpectedControlLayoutFilter(control.layout))
                {
                    parent.AddChild(child);
                }
                else if (controlLayout.controls.Any(x => LayoutMatchesExpectedControlLayoutFilter(x.layout)))
                {
                    child.enabled = false;
                    parent.AddChild(child);
                }
                // Add children.
                if (controlLayout != null)
                {
                    AddControlTreeItemsRecursive(controlPickerLayout, controlLayout, parent, device, usage,
                                                 searchable, child);
                }
            }
        }
        private void BuildControlTypeList()
        {
            var types      = new List <string>();
            var allLayouts = InputSystem.s_Manager.m_Layouts;

            foreach (var layoutName in allLayouts.layoutTypes.Keys)
            {
                if (EditorInputControlLayoutCache.TryGetLayout(layoutName).hideInUI)
                {
                    continue;
                }

                // If the action type is InputActionType.Value, skip button controls.
                var type = allLayouts.layoutTypes[layoutName];
                if ((InputActionType)m_SelectedActionType == InputActionType.Value &&
                    typeof(ButtonControl).IsAssignableFrom(type))
                {
                    continue;
                }

                ////TODO: skip aliases

                if (typeof(InputControl).IsAssignableFrom(type) &&
                    !typeof(InputDevice).IsAssignableFrom(type))
                {
                    types.Add(layoutName);
                }
            }
            // Sort alphabetically.
            types.Sort((a, b) => string.Compare(a, b, StringComparison.OrdinalIgnoreCase));
            // Make sure "Any" is always topmost entry.
            types.Insert(0, "Any");

            m_ControlTypeList    = types.ToArray();
            m_ControlTypeOptions = m_ControlTypeList.Select(x => new GUIContent(ObjectNames.NicifyVariableName(x)))
                                   .ToArray();
        }
Exemplo n.º 9
0
            private void AddControlItem(InputControlLayout.ControlItem control, TreeViewItem parent, ref int id)
            {
                var item = AddChild(parent, control.variants.IsEmpty() ? control.name : string.Format("{0} ({1})",
                                                                                                      control.name, control.variants), ref id);

                if (!control.layout.IsEmpty())
                {
                    item.icon = EditorInputControlLayoutCache.GetIconForLayout(control.layout);
                }

                ////TODO: fully merge TreeViewItems from isModifyingExistingControl control layouts into the control they modify

                ////TODO: allow clicking this field to jump to the layout
                if (!control.layout.IsEmpty())
                {
                    AddChild(item, $"Layout: {control.layout}", ref id);
                }
                if (!control.variants.IsEmpty())
                {
                    AddChild(item, $"Variant: {control.variants}", ref id);
                }
                if (!string.IsNullOrEmpty(control.displayName))
                {
                    AddChild(item, $"Display Name: {control.displayName}", ref id);
                }
                if (!string.IsNullOrEmpty(control.shortDisplayName))
                {
                    AddChild(item, $"Short Display Name: {control.shortDisplayName}", ref id);
                }
                if (control.format != 0)
                {
                    AddChild(item, $"Format: {control.format}", ref id);
                }
                if (control.offset != InputStateBlock.InvalidOffset)
                {
                    AddChild(item, $"Offset: {control.offset}", ref id);
                }
                if (control.bit != InputStateBlock.InvalidOffset)
                {
                    AddChild(item, $"Bit: {control.bit}", ref id);
                }
                if (control.sizeInBits != 0)
                {
                    AddChild(item, $"Size In Bits: {control.sizeInBits}", ref id);
                }
                if (control.isArray)
                {
                    AddChild(item, $"Array Size: {control.arraySize}", ref id);
                }
                if (!string.IsNullOrEmpty(control.useStateFrom))
                {
                    AddChild(item, $"Use State From: {control.useStateFrom}", ref id);
                }
                if (!control.defaultState.isEmpty)
                {
                    AddChild(item, $"Default State: {control.defaultState.ToString()}", ref id);
                }
                if (!control.minValue.isEmpty)
                {
                    AddChild(item, $"Min Value: {control.minValue.ToString()}", ref id);
                }
                if (!control.maxValue.isEmpty)
                {
                    AddChild(item, $"Max Value: {control.maxValue.ToString()}", ref id);
                }

                if (control.usages.Count > 0)
                {
                    AddChild(item, "Usages: " + string.Join(", ", control.usages.Select(x => x.ToString()).ToArray()), ref id);
                }
                if (control.aliases.Count > 0)
                {
                    AddChild(item, "Aliases: " + string.Join(", ", control.aliases.Select(x => x.ToString()).ToArray()), ref id);
                }

                if (control.isNoisy || control.isSynthetic)
                {
                    var flags = "Flags: ";
                    if (control.isNoisy)
                    {
                        flags += "Noisy";
                    }
                    if (control.isSynthetic)
                    {
                        if (control.isNoisy)
                        {
                            flags += ", Synthetic";
                        }
                        else
                        {
                            flags += "Synthetic";
                        }
                    }
                    AddChild(item, flags, ref id);
                }

                if (control.parameters.Count > 0)
                {
                    var parameters = AddChild(item, "Parameters", ref id);
                    foreach (var parameter in control.parameters)
                    {
                        AddChild(parameters, parameter.ToString(), ref id);
                    }
                }

                if (control.processors.Count > 0)
                {
                    var processors = AddChild(item, "Processors", ref id);
                    foreach (var processor in control.processors)
                    {
                        var processorItem = AddChild(processors, processor.name, ref id);
                        foreach (var parameter in processor.parameters)
                        {
                            AddChild(processorItem, parameter.ToString(), ref id);
                        }
                    }
                }
            }
Exemplo n.º 10
0
            private TreeViewItem AddControlLayoutItem(InputControlLayout layout, TreeViewItem parent, ref int id)
            {
                var item = new LayoutItem
                {
                    parent      = parent,
                    depth       = parent.depth + 1,
                    id          = id++,
                    displayName = layout.displayName ?? layout.name,
                    layoutName  = layout.name,
                };

                item.icon = EditorInputControlLayoutCache.GetIconForLayout(layout.name);
                parent.AddChild(item);

                // Header.
                AddChild(item, "Type: " + layout.type.Name, ref id);
                if (!string.IsNullOrEmpty(layout.m_DisplayName))
                {
                    AddChild(item, "Display Name: " + layout.m_DisplayName, ref id);
                }
                var baseLayouts = StringHelpers.Join(layout.baseLayouts, ", ");

                if (!string.IsNullOrEmpty(baseLayouts))
                {
                    AddChild(item, "Extends: " + baseLayouts, ref id);
                }
                if (layout.stateFormat != 0)
                {
                    AddChild(item, "Format: " + layout.stateFormat, ref id);
                }
                if (layout.m_UpdateBeforeRender != null)
                {
                    var value = layout.m_UpdateBeforeRender.Value ? "Update" : "Disabled";
                    AddChild(item, "Before Render: " + value, ref id);
                }
                if (layout.commonUsages.Count > 0)
                {
                    AddChild(item,
                             "Common Usages: " +
                             string.Join(", ", layout.commonUsages.Select(x => x.ToString()).ToArray()),
                             ref id);
                }
                if (layout.appliedOverrides.Count() > 0)
                {
                    AddChild(item,
                             "Applied Overrides: " +
                             string.Join(", ", layout.appliedOverrides),
                             ref id);
                }

                ////TODO: find a more elegant solution than multiple "Matching Devices" parents when having multiple
                ////      matchers
                // Device matchers.
                foreach (var matcher in EditorInputControlLayoutCache.GetDeviceMatchers(layout.name))
                {
                    var node = AddChild(item, "Matching Devices", ref id);
                    foreach (var pattern in matcher.patterns)
                    {
                        AddChild(node, $"{pattern.Key} => \"{pattern.Value}\"", ref id);
                    }
                }

                // Controls.
                if (layout.controls.Count > 0)
                {
                    var controls = AddChild(item, "Controls", ref id);
                    foreach (var control in layout.controls)
                    {
                        AddControlItem(control, controls, ref id);
                    }

                    controls.children.Sort((a, b) => string.Compare(a.displayName, b.displayName));
                }

                return(item);
            }
Exemplo n.º 11
0
            protected override TreeViewItem BuildRoot()
            {
                var id = 0;

                var root = new TreeViewItem
                {
                    id    = id++,
                    depth = -1
                };

                ////TODO: this will need to be improved for multi-user scenarios
                // Actions.
                m_EnabledActions.Clear();
                InputSystem.ListEnabledActions(m_EnabledActions);
                if (m_EnabledActions.Count > 0)
                {
                    actionsItem = AddChild(root, "", ref id);
                    AddEnabledActions(actionsItem, ref id);

                    if (!actionsItem.hasChildren)
                    {
                        // We are culling actions that are assigned to users so we may end up with an empty
                        // list even if we have enabled actions. If we do, remove the "Actions" item from the tree.
                        root.children.Remove(actionsItem);
                    }
                    else
                    {
                        // Update title to include action count.
                        actionsItem.displayName = $"Actions ({actionsItem.children.Count})";
                    }
                }

                // Users.
                var userCount = InputUser.all.Count;

                if (userCount > 0)
                {
                    usersItem = AddChild(root, $"Users ({userCount})", ref id);
                    foreach (var user in InputUser.all)
                    {
                        AddUser(usersItem, user, ref id);
                    }
                }

                // Devices.
                var devices = InputSystem.devices;

                devicesItem = AddChild(root, $"Devices ({devices.Count})", ref id);
                var          haveRemotes      = devices.Any(x => x.remote);
                TreeViewItem localDevicesNode = null;

                if (haveRemotes)
                {
                    // Split local and remote devices into groups.

                    localDevicesNode = AddChild(devicesItem, "Local", ref id);
                    AddDevices(localDevicesNode, devices, ref id);

                    var remoteDevicesNode = AddChild(devicesItem, "Remote", ref id);
                    foreach (var player in EditorConnection.instance.ConnectedPlayers)
                    {
                        var playerNode = AddChild(remoteDevicesNode, player.name, ref id);
                        AddDevices(playerNode, devices, ref id, player.playerId);
                    }
                }
                else
                {
                    // We don't have remote devices so don't add an extra group for local devices.
                    // Put them all directly underneath the "Devices" node.
                    AddDevices(devicesItem, devices, ref id);
                }

                ////TDO: unsupported and disconnected devices should also be shown for remotes

                if (m_UnsupportedDevices == null)
                {
                    m_UnsupportedDevices = new List <InputDeviceDescription>();
                }
                m_UnsupportedDevices.Clear();
                InputSystem.GetUnsupportedDevices(m_UnsupportedDevices);
                if (m_UnsupportedDevices.Count > 0)
                {
                    var parent = haveRemotes ? localDevicesNode : devicesItem;
                    var unsupportedDevicesNode = AddChild(parent, $"Unsupported ({m_UnsupportedDevices.Count})", ref id);
                    foreach (var device in m_UnsupportedDevices)
                    {
                        var item = new UnsupportedDeviceItem
                        {
                            id          = id++,
                            depth       = unsupportedDevicesNode.depth + 1,
                            displayName = device.ToString(),
                            description = device
                        };
                        unsupportedDevicesNode.AddChild(item);
                    }
                    unsupportedDevicesNode.children.Sort((a, b) =>
                                                         string.Compare(a.displayName, b.displayName, StringComparison.InvariantCulture));
                }

                var disconnectedDevices = InputSystem.disconnectedDevices;

                if (disconnectedDevices.Count > 0)
                {
                    var parent = haveRemotes ? localDevicesNode : devicesItem;
                    var disconnectedDevicesNode = AddChild(parent, $"Disconnected ({disconnectedDevices.Count})", ref id);
                    foreach (var device in disconnectedDevices)
                    {
                        AddChild(disconnectedDevicesNode, device.ToString(), ref id);
                    }
                    disconnectedDevicesNode.children.Sort((a, b) =>
                                                          string.Compare(a.displayName, b.displayName, StringComparison.InvariantCulture));
                }

                // Layouts.
                layoutsItem = AddChild(root, "Layouts", ref id);
                AddControlLayouts(layoutsItem, ref id);

                ////FIXME: this shows local configuration only
                // Settings.
                var settings          = InputSystem.settings;
                var settingsAssetPath = AssetDatabase.GetAssetPath(settings);
                var settingsLabel     = "Settings";

                if (!string.IsNullOrEmpty(settingsAssetPath))
                {
                    settingsLabel = $"Settings ({Path.GetFileName(settingsAssetPath)})";
                }
                settingsItem = AddChild(root, settingsLabel, ref id);
                AddValueItem(settingsItem, "Update Mode", settings.updateMode, ref id);
                AddValueItem(settingsItem, "Compensate For Screen Orientation", settings.compensateForScreenOrientation, ref id);
                AddValueItem(settingsItem, "Filter Noise On .current", settings.filterNoiseOnCurrent, ref id);
                AddValueItem(settingsItem, "Default Button Press Point", settings.defaultButtonPressPoint, ref id);
                AddValueItem(settingsItem, "Default Deadzone Min", settings.defaultDeadzoneMin, ref id);
                AddValueItem(settingsItem, "Default Deadzone Max", settings.defaultDeadzoneMax, ref id);
                AddValueItem(settingsItem, "Default Tap Time", settings.defaultTapTime, ref id);
                AddValueItem(settingsItem, "Default Slow Tap Time", settings.defaultSlowTapTime, ref id);
                AddValueItem(settingsItem, "Default Hold Time", settings.defaultHoldTime, ref id);
                AddValueItem(settingsItem, "Lock Input To Game View", InputEditorUserSettings.lockInputToGameView, ref id);
                if (settings.supportedDevices.Count > 0)
                {
                    var supportedDevices = AddChild(settingsItem, "Supported Devices", ref id);
                    foreach (var item in settings.supportedDevices)
                    {
                        var icon = EditorInputControlLayoutCache.GetIconForLayout(item);
                        AddChild(supportedDevices, item, ref id, icon);
                    }
                }
                settingsItem.children.Sort((a, b) => string.Compare(a.displayName, b.displayName));

                // Metrics.
                var metrics = InputSystem.metrics;

                metricsItem = AddChild(root, "Metrics", ref id);
                AddChild(metricsItem,
                         "Current State Size in Bytes: " + StringHelpers.NicifyMemorySize(metrics.currentStateSizeInBytes),
                         ref id);
                AddValueItem(metricsItem, "Current Control Count", metrics.currentControlCount, ref id);
                AddValueItem(metricsItem, "Current Layout Count", metrics.currentLayoutCount, ref id);

                return(root);
            }
Exemplo n.º 12
0
        /// <summary>
        /// Grab <see cref="InputSystem.settings"/> and set it up for editing.
        /// </summary>
        private void InitializeWithCurrentSettings()
        {
            // Find the set of available assets in the project.
            m_AvailableInputSettingsAssets = FindInputSettingsInProject();

            // See which is the active one.
            m_Settings           = InputSystem.settings;
            m_SettingsDirtyCount = EditorUtility.GetDirtyCount(m_Settings);
            var currentSettingsPath = AssetDatabase.GetAssetPath(m_Settings);

            if (string.IsNullOrEmpty(currentSettingsPath))
            {
                if (m_AvailableInputSettingsAssets.Length != 0)
                {
                    m_CurrentSelectedInputSettingsAsset = 0;
                    m_Settings           = AssetDatabase.LoadAssetAtPath <InputSettings>(m_AvailableInputSettingsAssets[0]);
                    InputSystem.settings = m_Settings;
                }
            }
            else
            {
                m_CurrentSelectedInputSettingsAsset = ArrayHelpers.IndexOf(m_AvailableInputSettingsAssets, currentSettingsPath);
                if (m_CurrentSelectedInputSettingsAsset == -1)
                {
                    // This is odd and shouldn't happen. Solve by just adding the path to the list.
                    m_CurrentSelectedInputSettingsAsset =
                        ArrayHelpers.Append(ref m_AvailableInputSettingsAssets, currentSettingsPath);
                }

                ////REVIEW: should we store this by platform?
                EditorBuildSettings.AddConfigObject(kEditorBuildSettingsConfigKey, m_Settings, true);
            }

            // Refresh the list of assets we display in the UI.
            m_AvailableSettingsAssetsOptions = new GUIContent[m_AvailableInputSettingsAssets.Length];
            for (var i = 0; i < m_AvailableInputSettingsAssets.Length; ++i)
            {
                var name = m_AvailableInputSettingsAssets[i];
                if (name.StartsWith("Assets/"))
                {
                    name = name.Substring("Assets/".Length);
                }
                if (name.EndsWith(".asset"))
                {
                    name = name.Substring(0, name.Length - ".asset".Length);
                }
                if (name.EndsWith(".inputsettings"))
                {
                    name = name.Substring(0, name.Length - ".inputsettings".Length);
                }

                // Ugly hack: GenericMenu interprets "/" as a submenu path. But luckily, "/" is not the only slash we have in Unicode.
                m_AvailableSettingsAssetsOptions[i] = new GUIContent(name.Replace("/", "\u29f8"));
            }

            // Look up properties.
            m_SettingsObject = new SerializedObject(m_Settings);
            m_UpdateMode     = m_SettingsObject.FindProperty("m_UpdateMode");
            m_CompensateForScreenOrientation = m_SettingsObject.FindProperty("m_CompensateForScreenOrientation");
            m_FilterNoiseOnCurrent           = m_SettingsObject.FindProperty("m_FilterNoiseOnCurrent");
            m_DefaultDeadzoneMin             = m_SettingsObject.FindProperty("m_DefaultDeadzoneMin");
            m_DefaultDeadzoneMax             = m_SettingsObject.FindProperty("m_DefaultDeadzoneMax");
            m_DefaultButtonPressPoint        = m_SettingsObject.FindProperty("m_DefaultButtonPressPoint");
            m_ButtonReleaseThreshold         = m_SettingsObject.FindProperty("m_ButtonReleaseThreshold");
            m_DefaultTapTime     = m_SettingsObject.FindProperty("m_DefaultTapTime");
            m_DefaultSlowTapTime = m_SettingsObject.FindProperty("m_DefaultSlowTapTime");
            m_DefaultHoldTime    = m_SettingsObject.FindProperty("m_DefaultHoldTime");
            m_TapRadius          = m_SettingsObject.FindProperty("m_TapRadius");
            m_MultiTapDelayTime  = m_SettingsObject.FindProperty("m_MultiTapDelayTime");

            m_UpdateModeContent                     = new GUIContent("Update Mode", "When should the Input System be updated?");
            m_FilterNoiseOnCurrentContent           = new GUIContent("Filter Noise on current", "If enabled, input from noisy controls will not cause a device to become '.current'.");
            m_CompensateForScreenOrientationContent = new GUIContent("Compensate Orientation", "Whether sensor input on mobile devices should be transformed to be relative to the current device orientation.");
            m_DefaultDeadzoneMinContent             = new GUIContent("Default Deadzone Min", "Default 'min' value for Stick Deadzone and Axis Deadzone processors.");
            m_DefaultDeadzoneMaxContent             = new GUIContent("Default Deadzone Max", "Default 'max' value for Stick Deadzone and Axis Deadzone processors.");
            m_DefaultButtonPressPointContent        = new GUIContent("Default Button Press Point", "The default press point used for Button controls as well as for various interactions. For button controls which have analog physical inputs, this configures how far they need to   be held down to be considered 'pressed'.");
            m_ButtonReleaseThresholdContent         = new GUIContent("Button Release Threshold", "Percent of press point at which a Button is considered released again. At 1, release points are identical to press points. At 0, a Button must be fully released before it can be pressed again.");
            m_DefaultTapTimeContent                 = new GUIContent("Default Tap Time", "Default duration to be used for Tap and MultiTap interactions. Also used by by Touch screen devices to distinguish taps from to new touches.");
            m_DefaultSlowTapTimeContent             = new GUIContent("Default Slow Tap Time", "Default duration to be used for SlowTap interactions.");
            m_DefaultHoldTimeContent                = new GUIContent("Default Hold Time", "Default duration to be used for Hold interactions.");
            m_TapRadiusContent         = new GUIContent("Tap Radius", "Maximum distance between two finger taps on a touch screen device allowed for the system to consider this a tap of the same touch (as opposed to a new touch).");
            m_MultiTapDelayTimeContent = new GUIContent("MultiTap Delay Time", "Default delay to be allowed between taps for MultiTap interactions. Also used by by touch devices to count multi taps.");

            // Initialize ReorderableList for list of supported devices.
            var supportedDevicesProperty = m_SettingsObject.FindProperty("m_SupportedDevices");

            m_SupportedDevices = new ReorderableList(m_SettingsObject, supportedDevicesProperty)
            {
                drawHeaderCallback =
                    rect => { EditorGUI.LabelField(rect, m_SupportedDevicesText); },
                onChangedCallback =
                    list => { Apply(); },
                onAddDropdownCallback =
                    (rect, list) =>
                {
                    var dropdown = new InputControlPickerDropdown(
                        new InputControlPickerState(),
                        path =>
                    {
                        ////REVIEW: Why are we converting from a layout into a plain string here instead of just using path strings in supportedDevices?
                        ////        Why not just have InputSettings.supportedDevices be a list of paths?
                        var layoutName    = InputControlPath.TryGetDeviceLayout(path) ?? path;
                        var existingIndex = m_Settings.supportedDevices.IndexOf(x => x == layoutName);
                        if (existingIndex != -1)
                        {
                            m_SupportedDevices.index = existingIndex;
                            return;
                        }
                        var numDevices = supportedDevicesProperty.arraySize;
                        supportedDevicesProperty.InsertArrayElementAtIndex(numDevices);
                        supportedDevicesProperty.GetArrayElementAtIndex(numDevices)
                        .stringValue             = layoutName;
                        m_SupportedDevices.index = numDevices;
                        Apply();
                    },
                        mode: InputControlPicker.Mode.PickDevice);
                    dropdown.Show(rect);
                },
                drawElementCallback =
                    (rect, index, isActive, isFocused) =>
                {
                    var layoutName = m_Settings.supportedDevices[index];
                    var icon       = EditorInputControlLayoutCache.GetIconForLayout(layoutName);
                    if (icon != null)
                    {
                        var iconRect = rect;
                        iconRect.width = 20;
                        rect.x        += 20;
                        rect.width    -= 20;

                        GUI.Label(iconRect, icon);
                    }

                    EditorGUI.LabelField(rect, layoutName);
                }
            };

            m_iOSProvider = new InputSettingsiOSProvider(m_SettingsObject);
        }
Exemplo n.º 13
0
            protected override void ContextClickedItem(int id)
            {
                var item = FindItem(id, rootItem);

                if (item == null)
                {
                    return;
                }

                if (item is DeviceItem deviceItem)
                {
                    var menu = new GenericMenu();
                    menu.AddItem(Contents.openDebugView, false, () => InputDeviceDebuggerWindow.CreateOrShowExisting(deviceItem.device));
                    menu.AddItem(Contents.copyDeviceDescription, false,
                                 () => EditorGUIUtility.systemCopyBuffer = deviceItem.device.description.ToJson());
                    menu.AddItem(Contents.removeDevice, false, () => InputSystem.RemoveDevice(deviceItem.device));
                    if (deviceItem.device.enabled)
                    {
                        menu.AddItem(Contents.disableDevice, false, () => InputSystem.DisableDevice(deviceItem.device));
                    }
                    else
                    {
                        menu.AddItem(Contents.enableDevice, false, () => InputSystem.EnableDevice(deviceItem.device));
                    }
                    menu.ShowAsContext();
                }

                if (item is UnsupportedDeviceItem unsupportedDeviceItem)
                {
                    var menu = new GenericMenu();
                    menu.AddItem(Contents.copyDeviceDescription, false,
                                 () => EditorGUIUtility.systemCopyBuffer = unsupportedDeviceItem.description.ToJson());
                    menu.ShowAsContext();
                }

                if (item is LayoutItem layoutItem)
                {
                    var layout = EditorInputControlLayoutCache.TryGetLayout(layoutItem.layoutName);
                    if (layout != null)
                    {
                        var menu = new GenericMenu();
                        menu.AddItem(Contents.copyLayoutAsJSON, false,
                                     () => EditorGUIUtility.systemCopyBuffer = layout.ToJson());
                        if (layout.isDeviceLayout)
                        {
                            menu.AddItem(Contents.createDeviceFromLayout, false,
                                         () => InputSystem.AddDevice(layout.name));
                            menu.AddItem(Contents.generateCodeFromLayout, false, () =>
                            {
                                var fileName   = EditorUtility.SaveFilePanel("Generate InputDevice Code", "", "Fast" + layoutItem.layoutName, "cs");
                                var isInAssets = fileName.StartsWith(Application.dataPath, StringComparison.OrdinalIgnoreCase);
                                if (isInAssets)
                                {
                                    fileName = "Assets/" + fileName.Substring(Application.dataPath.Length + 1);
                                }
                                if (!string.IsNullOrEmpty(fileName))
                                {
                                    var code = InputLayoutCodeGenerator.GenerateCodeFileForDeviceLayout(layoutItem.layoutName, fileName, prefix: "Fast");
                                    File.WriteAllText(fileName, code);
                                    if (isInAssets)
                                    {
                                        AssetDatabase.Refresh();
                                    }
                                }
                            });
                        }
                        menu.ShowAsContext();
                    }
                }
            }
Exemplo n.º 14
0
        /// <summary>
        /// Grab <see cref="InputSystem.settings"/> and set it up for editing.
        /// </summary>
        private void InitializeWithCurrentSettings()
        {
            // Find the set of available assets in the project.
            m_AvailableInputSettingsAssets = FindInputSettingsInProject();

            // See which is the active one.
            m_Settings           = InputSystem.settings;
            m_SettingsDirtyCount = EditorUtility.GetDirtyCount(m_Settings);
            var currentSettingsPath = AssetDatabase.GetAssetPath(m_Settings);

            if (string.IsNullOrEmpty(currentSettingsPath))
            {
                if (m_AvailableInputSettingsAssets.Length != 0)
                {
                    m_CurrentSelectedInputSettingsAsset = 0;
                    m_Settings           = AssetDatabase.LoadAssetAtPath <InputSettings>(m_AvailableInputSettingsAssets[0]);
                    InputSystem.settings = m_Settings;
                }
            }
            else
            {
                m_CurrentSelectedInputSettingsAsset = ArrayHelpers.IndexOf(m_AvailableInputSettingsAssets, currentSettingsPath);
                if (m_CurrentSelectedInputSettingsAsset == -1)
                {
                    // This is odd and shouldn't happen. Solve by just adding the path to the list.
                    m_CurrentSelectedInputSettingsAsset =
                        ArrayHelpers.Append(ref m_AvailableInputSettingsAssets, currentSettingsPath);
                }

                ////REVIEW: should we store this by platform?
                EditorBuildSettings.AddConfigObject(kEditorBuildSettingsConfigKey, m_Settings, true);
            }

            // Refresh the list of assets we display in the UI.
            m_AvailableSettingsAssetsOptions = new GUIContent[m_AvailableInputSettingsAssets.Length];
            for (var i = 0; i < m_AvailableInputSettingsAssets.Length; ++i)
            {
                var name = m_AvailableInputSettingsAssets[i];
                if (name.StartsWith("Assets/"))
                {
                    name = name.Substring("Assets/".Length);
                }
                if (name.EndsWith(".asset"))
                {
                    name = name.Substring(0, name.Length - ".asset".Length);
                }
                if (name.EndsWith(".inputsettings"))
                {
                    name = name.Substring(0, name.Length - ".inputsettings".Length);
                }

                // Ugly hack: GenericMenu interprets "/" as a submenu path. But luckily, "/" is not the only slash we have in Unicode.
                m_AvailableSettingsAssetsOptions[i] = new GUIContent(name.Replace("/", "\u29f8"));
            }

            // Look up properties.
            m_SettingsObject = new SerializedObject(m_Settings);
            m_UpdateMode     = m_SettingsObject.FindProperty("m_UpdateMode");
            m_CompensateForScreenOrientation = m_SettingsObject.FindProperty("m_CompensateForScreenOrientation");
            m_BackgroundBehavior             = m_SettingsObject.FindProperty("m_BackgroundBehavior");
            m_EditorInputBehaviorInPlayMode  = m_SettingsObject.FindProperty("m_EditorInputBehaviorInPlayMode");
            m_DefaultDeadzoneMin             = m_SettingsObject.FindProperty("m_DefaultDeadzoneMin");
            m_DefaultDeadzoneMax             = m_SettingsObject.FindProperty("m_DefaultDeadzoneMax");
            m_DefaultButtonPressPoint        = m_SettingsObject.FindProperty("m_DefaultButtonPressPoint");
            m_ButtonReleaseThreshold         = m_SettingsObject.FindProperty("m_ButtonReleaseThreshold");
            m_DefaultTapTime     = m_SettingsObject.FindProperty("m_DefaultTapTime");
            m_DefaultSlowTapTime = m_SettingsObject.FindProperty("m_DefaultSlowTapTime");
            m_DefaultHoldTime    = m_SettingsObject.FindProperty("m_DefaultHoldTime");
            m_TapRadius          = m_SettingsObject.FindProperty("m_TapRadius");
            m_MultiTapDelayTime  = m_SettingsObject.FindProperty("m_MultiTapDelayTime");

            m_UpdateModeContent = new GUIContent("Update Mode", "When should the Input System be updated?");
            m_CompensateForScreenOrientationContent = new GUIContent("Compensate Orientation", "Whether sensor input on mobile devices should be transformed to be relative to the current device orientation.");
            m_BackgroundBehaviorContent             = new GUIContent("Background Behavior", "If runInBackground is true (and in standalone *development* players and the editor), "
                                                                     + "determines what happens to InputDevices and events when the application moves in and out of running in the foreground.\n\n"
                                                                     + "'Reset And Disable Non-Background Devices' soft-resets and disables devices that cannot run in the background while the application does not have focus. Devices "
                                                                     + "that can run in the background remain enabled and will keep receiving input.\n"
                                                                     + "'Reset And Disable All Devices' soft-resets and disables *all* devices while the application does not have focus. No device will receive input while the application "
                                                                     + "is running in the background.\n"
                                                                     + "'Ignore Focus' leaves all devices untouched when application focus changes. While running in the background, all input that is received is processed as if "
                                                                     + "running in the foreground.");
            m_EditorInputBehaviorInPlayModeContent = new GUIContent("Play Mode Input Behavior", "When in play mode, determines how focus of the Game View is handled with respect to input.\n\n"
                                                                    + "'Pointers And Keyboards Respect Game View Focus' requires Game View focus only for pointers (mice, touch, etc.) and keyboards. Other devices will feed input to the game regardless "
                                                                    + "of whether the Game View is focused or not. Note that this means that input on these devices is not visible in other EditorWindows.\n"
                                                                    + "'All Devices Respect Game View Focus' requires Game View focus for all input devices. While focus is not on the Game View, all input on InputDevices will go to the editor and not "
                                                                    + "the game.\n"
                                                                    + "'All Device Input Always Goes To Game View' causes input to treat 'Background Behavior' exactly as in the player including devices potentially being disabled entirely while the Game View "
                                                                    + "does not have focus. In this setting, no input from the Input System will be visible to EditorWindows.");
            m_DefaultDeadzoneMinContent      = new GUIContent("Default Deadzone Min", "Default 'min' value for Stick Deadzone and Axis Deadzone processors.");
            m_DefaultDeadzoneMaxContent      = new GUIContent("Default Deadzone Max", "Default 'max' value for Stick Deadzone and Axis Deadzone processors.");
            m_DefaultButtonPressPointContent = new GUIContent("Default Button Press Point", "The default press point used for Button controls as well as for various interactions. For button controls which have analog physical inputs, this configures how far they need to   be held down to be considered 'pressed'.");
            m_ButtonReleaseThresholdContent  = new GUIContent("Button Release Threshold", "Percent of press point at which a Button is considered released again. At 1, release points are identical to press points. At 0, a Button must be fully released before it can be pressed again.");
            m_DefaultTapTimeContent          = new GUIContent("Default Tap Time", "Default duration to be used for Tap and MultiTap interactions. Also used by by Touch screen devices to distinguish taps from to new touches.");
            m_DefaultSlowTapTimeContent      = new GUIContent("Default Slow Tap Time", "Default duration to be used for SlowTap interactions.");
            m_DefaultHoldTimeContent         = new GUIContent("Default Hold Time", "Default duration to be used for Hold interactions.");
            m_TapRadiusContent         = new GUIContent("Tap Radius", "Maximum distance between two finger taps on a touch screen device allowed for the system to consider this a tap of the same touch (as opposed to a new touch).");
            m_MultiTapDelayTimeContent = new GUIContent("MultiTap Delay Time", "Default delay to be allowed between taps for MultiTap interactions. Also used by by touch devices to count multi taps.");

            // Initialize ReorderableList for list of supported devices.
            var supportedDevicesProperty = m_SettingsObject.FindProperty("m_SupportedDevices");

            m_SupportedDevices = new ReorderableList(m_SettingsObject, supportedDevicesProperty)
            {
                drawHeaderCallback =
                    rect => { EditorGUI.LabelField(rect, m_SupportedDevicesText); },
                onChangedCallback =
                    list => { Apply(); },
                onAddDropdownCallback =
                    (rect, list) =>
                {
                    var dropdown = new InputControlPickerDropdown(
                        new InputControlPickerState(),
                        path =>
                    {
                        ////REVIEW: Why are we converting from a layout into a plain string here instead of just using path strings in supportedDevices?
                        ////        Why not just have InputSettings.supportedDevices be a list of paths?
                        var layoutName    = InputControlPath.TryGetDeviceLayout(path) ?? path;
                        var existingIndex = m_Settings.supportedDevices.IndexOf(x => x == layoutName);
                        if (existingIndex != -1)
                        {
                            m_SupportedDevices.index = existingIndex;
                            return;
                        }
                        var numDevices = supportedDevicesProperty.arraySize;
                        supportedDevicesProperty.InsertArrayElementAtIndex(numDevices);
                        supportedDevicesProperty.GetArrayElementAtIndex(numDevices)
                        .stringValue             = layoutName;
                        m_SupportedDevices.index = numDevices;
                        Apply();
                    },
                        mode: InputControlPicker.Mode.PickDevice);
                    dropdown.Show(rect);
                },
                drawElementCallback =
                    (rect, index, isActive, isFocused) =>
                {
                    var layoutName = m_Settings.supportedDevices[index];
                    var icon       = EditorInputControlLayoutCache.GetIconForLayout(layoutName);
                    if (icon != null)
                    {
                        var iconRect = rect;
                        iconRect.width = 20;
                        rect.x        += 20;
                        rect.width    -= 20;

                        GUI.Label(iconRect, icon);
                    }

                    EditorGUI.LabelField(rect, layoutName);
                }
            };

            m_iOSProvider = new InputSettingsiOSProvider(m_SettingsObject);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Grab <see cref="InputSystem.settings"/> and set it up for editing.
        /// </summary>
        private void InitializeWithCurrentSettings()
        {
            // Find the set of available assets in the project.
            m_AvailableInputSettingsAssets = FindInputSettingsInProject();

            // See which is the active one.
            m_Settings = InputSystem.settings;
            var currentSettingsPath = AssetDatabase.GetAssetPath(m_Settings);

            if (string.IsNullOrEmpty(currentSettingsPath))
            {
                if (m_AvailableInputSettingsAssets.Length != 0)
                {
                    m_CurrentSelectedInputSettingsAsset = 0;
                    m_Settings           = AssetDatabase.LoadAssetAtPath <InputSettings>(m_AvailableInputSettingsAssets[0]);
                    InputSystem.settings = m_Settings;
                }
            }
            else
            {
                m_CurrentSelectedInputSettingsAsset = ArrayHelpers.IndexOf(m_AvailableInputSettingsAssets, currentSettingsPath);
                if (m_CurrentSelectedInputSettingsAsset == -1)
                {
                    // This is odd and shouldn't happen. Solve by just adding the path to the list.
                    m_CurrentSelectedInputSettingsAsset =
                        ArrayHelpers.Append(ref m_AvailableInputSettingsAssets, currentSettingsPath);
                }

                ////REVIEW: should we store this by platform?
                EditorBuildSettings.AddConfigObject(kEditorBuildSettingsConfigKey, m_Settings, true);
            }

            // Refresh the list of assets we display in the UI.
            m_AvailableSettingsAssetsOptions = new GUIContent[m_AvailableInputSettingsAssets.Length];
            for (var i = 0; i < m_AvailableInputSettingsAssets.Length; ++i)
            {
                var name = m_AvailableInputSettingsAssets[i];
                if (name.StartsWith("Assets/"))
                {
                    name = name.Substring("Assets/".Length);
                }
                if (name.EndsWith(".asset"))
                {
                    name = name.Substring(0, name.Length - ".asset".Length);
                }
                if (name.EndsWith(".inputsettings"))
                {
                    name = name.Substring(0, name.Length - ".inputsettings".Length);
                }

                // Ugly hack: GenericMenu iterprets "/" as a submenu path. But luckily, "/" is not the only slash we have in Unicode.
                m_AvailableSettingsAssetsOptions[i] = new GUIContent(name.Replace("/", "\u29f8"));
            }

            // Look up properties.
            m_SettingsObject = new SerializedObject(m_Settings);
            m_UpdateMode     = m_SettingsObject.FindProperty("m_UpdateMode");
            m_CompensateForScreenOrientation = m_SettingsObject.FindProperty("m_CompensateForScreenOrientation");
            m_FilterNoiseOnCurrent           = m_SettingsObject.FindProperty("m_FilterNoiseOnCurrent");
            m_DefaultDeadzoneMin             = m_SettingsObject.FindProperty("m_DefaultDeadzoneMin");
            m_DefaultDeadzoneMax             = m_SettingsObject.FindProperty("m_DefaultDeadzoneMax");
            m_DefaultButtonPressPoint        = m_SettingsObject.FindProperty("m_DefaultButtonPressPoint");
            m_DefaultTapTime     = m_SettingsObject.FindProperty("m_DefaultTapTime");
            m_DefaultSlowTapTime = m_SettingsObject.FindProperty("m_DefaultSlowTapTime");
            m_DefaultHoldTime    = m_SettingsObject.FindProperty("m_DefaultHoldTime");
            m_TapRadius          = m_SettingsObject.FindProperty("m_TapRadius");
            m_MultiTapDelayTime  = m_SettingsObject.FindProperty("m_MultiTapDelayTime");

            // Initialize ReorderableList for list of supported devices.
            var supportedDevicesProperty = m_SettingsObject.FindProperty("m_SupportedDevices");

            m_SupportedDevices = new ReorderableList(m_SettingsObject, supportedDevicesProperty)
            {
                drawHeaderCallback =
                    rect => { EditorGUI.LabelField(rect, m_SupportedDevicesText); },
                onChangedCallback =
                    list => { Apply(); },
                onAddDropdownCallback =
                    (rect, list) =>
                {
                    var dropdown = new InputControlPickerDropdown(
                        new InputControlPickerState(),
                        path =>
                    {
                        var layoutName    = InputControlPath.TryGetDeviceLayout(path) ?? path;
                        var existingIndex = m_Settings.supportedDevices.IndexOf(x => x == layoutName);
                        if (existingIndex != -1)
                        {
                            m_SupportedDevices.index = existingIndex;
                            return;
                        }
                        var numDevices = supportedDevicesProperty.arraySize;
                        supportedDevicesProperty.InsertArrayElementAtIndex(numDevices);
                        supportedDevicesProperty.GetArrayElementAtIndex(numDevices)
                        .stringValue             = layoutName;
                        m_SupportedDevices.index = numDevices;
                        Apply();
                    },
                        mode: InputControlPicker.Mode.PickDevice);
                    dropdown.Show(rect);
                },
                drawElementCallback =
                    (rect, index, isActive, isFocused) =>
                {
                    var layoutName = m_Settings.supportedDevices[index];
                    var icon       = EditorInputControlLayoutCache.GetIconForLayout(layoutName);
                    if (icon != null)
                    {
                        var iconRect = rect;
                        iconRect.width = 20;
                        rect.x        += 20;
                        rect.width    -= 20;

                        GUI.Label(iconRect, icon);
                    }

                    EditorGUI.LabelField(rect, m_Settings.supportedDevices[index]);
                }
            };
        }