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); } } }
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; } ////TODO: skip aliases if (typeof(InputControl).IsAssignableFrom(allLayouts.layoutTypes[layoutName]) && !typeof(InputDevice).IsAssignableFrom(allLayouts.layoutTypes[layoutName])) { 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(); }
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); } } }
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.ShowAsContext(); } } }
// 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)); }
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(); } } }