示例#1
0
        private void AddControlItem(DeviceDropdownItem parent, ControlDropdownItem parentControl,
                                    InputControlLayout.ControlItem control, string device, string usage, bool searchable)
        {
            // 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 ? control.name + i : control.name;
                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(controlLayout, parent, device, usage,
                                                 searchable, child);
                }
            }
        }
        public void AddControlItem(InputControlPickerDropdown dropdown, DeviceDropdownItem parent, ControlDropdownItem parentControl,
                                   InputControlLayout.ControlItem control, string device, string usage, bool searchable)
        {
            // for the Press control, show two variants, one for single touch presses, and another for multi-touch presses
            if (control.displayName == "Press")
            {
                dropdown.AddControlItem(this, parent, parentControl, new InputControlLayout.ControlItem
                {
                    name        = new InternedString("Press"),
                    displayName = new InternedString("Press (Single touch)"),
                    layout      = control.layout
                }, device, usage, searchable);

                dropdown.AddControlItem(this, parent, parentControl, new InputControlLayout.ControlItem
                {
                    name        = new InternedString("Press"),
                    displayName = new InternedString("Press (Multi-touch)"),
                    layout      = control.layout
                }, device, usage, searchable, "touch*/Press");
            }
            else
            {
                dropdown.AddControlItem(this, parent, parentControl, control, device, usage, searchable);
            }
        }
示例#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;
                }

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

                if (LayoutMatchesExpectedControlLayoutFilter(control.layout))
                {
                    parent.AddChild(child);
                }

                var controlLayout = EditorInputControlLayoutCache.TryGetLayout(control.layout);
                if (controlLayout != null)
                {
                    AddControlTreeItemsRecursive(controlLayout, parent, device, usage,
                                                 searchable, child);
                }
            }

            // 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)
                {
                    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);
                }
            }
        }
示例#4
0
        private void AddDeviceTreeItemRecursive(InputControlLayout layout, AdvancedDropdownItem parent, bool searchable = true)
        {
            // Find all layouts directly based on this one.
            var childLayouts = EditorInputControlLayoutCache.allLayouts
                               .Where(x => x.isDeviceLayout && !x.hideInUI && x.baseLayouts.Contains(layout.name)).OrderBy(x => x.displayName);

            // See if the entire tree should be excluded.
            var shouldIncludeDeviceLayout          = ShouldIncludeDeviceLayout(layout);
            var shouldIncludeAtLeastOneChildLayout = childLayouts.Any(ShouldIncludeDeviceLayout);

            if (!shouldIncludeDeviceLayout && !shouldIncludeAtLeastOneChildLayout)
            {
                return;
            }

            // Add toplevel item for device.
            var deviceItem = new DeviceDropdownItem(layout, searchable: searchable);

            parent.AddChild(deviceItem);

            // Add common usage variants.
            if (m_Mode != InputControlPicker.Mode.PickDevice && layout.commonUsages.Count > 0)
            {
                foreach (var usage in layout.commonUsages)
                {
                    var usageItem = new DeviceDropdownItem(layout, usage);
                    AddControlTreeItemsRecursive(layout, usageItem, layout.name, usage, searchable);
                    deviceItem.AddChild(usageItem);
                }
                deviceItem.AddSeparator();
            }

            // Add controls.
            var haveControls = false;

            if (shouldIncludeDeviceLayout && m_Mode != InputControlPicker.Mode.PickDevice)
            {
                var childCountBefore = deviceItem.children.Count();

                // The keyboard is special in that we want to allow binding by display name (i.e. character
                // generated by a key) instead of only by physical key location. Also, we want to give an indication
                // of which specific key an entry refers to by taking the current keyboard layout into account.
                //
                // So what we do is add an extra level to the keyboard where key's can be bound by character
                // according to the current layout. And in the top level of the keyboard we display keys with
                // both physical and logical names.
                if (layout.type == typeof(Keyboard) && Keyboard.current != null)
                {
                    var byLocationGroup  = new AdvancedDropdownItem("By Location of Key (Using US Layout)");
                    var byCharacterGroup = new AdvancedDropdownItem("By Character Mapped to Key");

                    deviceItem.AddChild(byLocationGroup);
                    deviceItem.AddChild(byCharacterGroup);

                    var keyboard = Keyboard.current;

                    AddCharacterKeyBindingsTo(byCharacterGroup, keyboard);
                    AddPhysicalKeyBindingsTo(byLocationGroup, keyboard, searchable);
                }
                else
                {
                    AddControlTreeItemsRecursive(layout, deviceItem, layout.name, null, searchable);
                }

                haveControls = deviceItem.children.Count() != childCountBefore;
            }

            // Add child items.
            var isFirstChild = true;

            foreach (var childLayout in childLayouts)
            {
                if (!ShouldIncludeDeviceLayout(childLayout))
                {
                    continue;
                }

                if (isFirstChild && haveControls)
                {
                    deviceItem.AddSeparator("More Specific " + deviceItem.name.GetPlural());
                }
                isFirstChild = false;

                AddDeviceTreeItemRecursive(childLayout, deviceItem, searchable && !childLayout.isGenericTypeOfDevice);
            }

            // When picking devices, it must be possible to select a device that itself has more specific types
            // of devices underneath it. However in the dropdown, such a device will be a foldout and not itself
            // be selectable. We solve this problem by adding an entry for the device underneath the device
            // itself (e.g. "Gamepad >> Gamepad").
            if (m_Mode == InputControlPicker.Mode.PickDevice && deviceItem.m_Children.Count > 0)
            {
                var item = new DeviceDropdownItem(layout);
                deviceItem.m_Children.Insert(0, item);
            }
        }
 public void AddControlItem(InputControlPickerDropdown dropdown, DeviceDropdownItem parent,
                            ControlDropdownItem parentControl,
                            InputControlLayout.ControlItem control, string device, string usage, bool searchable)
 {
     dropdown.AddControlItem(this, parent, parentControl, control, device, usage, searchable);
 }