string ConvertPotentialAliasToName(InputControlLayout layout, string nameOrAlias) { InternedString internedNameOrAlias = new InternedString(nameOrAlias); ReadOnlyArray <InputControlLayout.ControlItem> controls = layout.controls; for (int i = 0; i < controls.Count; i++) { InputControlLayout.ControlItem controlItem = controls[i]; if (controlItem.name == internedNameOrAlias) { return(nameOrAlias); } ReadOnlyArray <InternedString> aliases = controlItem.aliases; for (int j = 0; j < aliases.Count; j++) { if (aliases[j] == nameOrAlias) { return(controlItem.name.ToString()); } } } return(nameOrAlias); }
private void AddDeviceTreeItem(InputControlLayout layout, AdvancedDropdownItem parent) { // Ignore devices that have no controls. We're looking at fully merged layouts here so // we're also taking inherited controls into account. if (layout.controls.Count == 0) { return; } var deviceItem = new DeviceTreeViewItem(layout); AddControlTreeItemsRecursive(layout, deviceItem, "", layout.name, null); if (deviceItem.children.Any()) { parent.AddChild(deviceItem); } foreach (var commonUsage in layout.commonUsages) { var commonUsageGroup = new DeviceTreeViewItem(layout, commonUsage); AddControlTreeItemsRecursive(layout, commonUsageGroup, "", layout.name, commonUsage); if (commonUsageGroup.children.Any()) { parent.AddChild(commonUsageGroup); } } }
private TreeViewItem AddControlLayoutItem(InputControlLayout layout, TreeViewItem parent, ref int id) { var item = AddChild(parent, layout.name, ref id); item.icon = EditorInputControlLayoutCache.GetIconForLayout(layout.name); // 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); } ////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); }
private static void ScanLayout(InputControlLayout layout) { foreach (var control in layout.controls) { // Collect unique usages and the layouts used with them. foreach (var usage in control.usages) { var internedUsage = new InternedString(usage); var internedLayout = new InternedString(control.layout); List <InternedString> layoutList; if (!s_Usages.TryGetValue(internedUsage, out layoutList)) { layoutList = new List <InternedString> { internedLayout }; s_Usages[internedUsage] = layoutList; } else { var layoutAlreadyInList = layoutList.Any(x => x == internedLayout); if (!layoutAlreadyInList) { layoutList.Add(internedLayout); } } } } }
private int ResolveProcessors(string processorString) { var firstProcessorIndex = totalProcessorCount; if (!InputControlLayout.ParseNameAndParameterList(processorString, ref m_Parameters)) { return(firstProcessorIndex); } for (var i = 0; i < m_Parameters.Count; ++i) { // Look up processor. var type = InputControlProcessor.s_Processors.LookupTypeRegistration(m_Parameters[i].name); if (type == null) { throw new Exception(string.Format( "No processor with name '{0}' (mentioned in '{1}') has been registered", m_Parameters[i].name, processorString)); } // Instantiate it. var processor = Activator.CreateInstance(type); // Pass parameters to it. InputDeviceBuilder.SetParameters(processor, m_Parameters[i].parameters); // Add to list. ArrayHelpers.AppendWithCapacity(ref processors, ref totalProcessorCount, processor); } return(firstProcessorIndex); }
private void AddChildControlIfMissing(InputControlLayout layout, InternedString variants, InputControl parent, ref bool haveChildrenUsingStateFromOtherControls, ref InputControlLayout.ControlItem controlItem) { ////TODO: support arrays (we may modify an entire array in bulk) // Find the child control. var child = InputControlPath.TryFindChild(parent, controlItem.name); if (child != null) { return; } // We're adding a child somewhere in the existing hierarchy. This is a tricky // case as we have to potentially shift indices around in the hierarchy to make // room for the new control. ////TODO: this path does not support recovering existing controls? does it matter? child = InsertChildControl(layout, variants, parent, ref haveChildrenUsingStateFromOtherControls, ref controlItem); // Apply layout change. if (!ReferenceEquals(child.parent, parent)) { ComputeStateLayout(child.parent); } }
private static void AddControlTreeItemsRecursive(InputControlLayout layout, TreeViewItem parent, string prefix, string deviceControlId, string commonUsage) { 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 ControlTreeViewItem(control, prefix, deviceControlId, commonUsage) { depth = parent.depth + 1, }; parent.AddChild(child); var childLayout = EditorInputControlLayoutCache.TryGetLayout(control.layout); if (childLayout != null) { AddControlTreeItemsRecursive(childLayout, parent, child.controlPath, deviceControlId, commonUsage); } } }
private static void AddDeviceTreeItem(InputControlLayout layout, TreeViewItem parent) { // Ignore devices that have no controls. We're looking at fully merged layouts here so // we're also taking inherited controls into account. if (layout.controls.Count == 0) { return; } var deviceItem = new DeviceTreeViewItem(layout) { depth = parent.depth + 1 }; AddControlTreeItemsRecursive(layout, deviceItem, "", layout.name, null); parent.AddChild(deviceItem); foreach (var commonUsage in layout.commonUsages) { var commonUsageGroup = new DeviceTreeViewItem(layout, commonUsage) { depth = parent.depth + 1 }; parent.AddChild(commonUsageGroup); AddControlTreeItemsRecursive(layout, commonUsageGroup, "", layout.name, commonUsage); } }
private static string ConvertPotentialAliasToName(InputControlLayout layout, string nameOrAlias) { var internedNameOrAlias = new InternedString(nameOrAlias); var controls = layout.controls; for (var i = 0; i < controls.Count; i++) { var controlItem = controls[i]; if (controlItem.name == internedNameOrAlias) { return(nameOrAlias); } var aliases = controlItem.aliases; for (var j = 0; j < aliases.Count; j++) { if (aliases[j] == nameOrAlias) { return(controlItem.name.ToString()); } } } return(nameOrAlias); }
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); } } }
public DeviceTreeViewItem(InputControlLayout layout, string commonUsage) { displayName = layout.name; if (commonUsage != null) { displayName += " (" + commonUsage + ")"; } id = (displayName).GetHashCode(); depth = 1; }
public DeviceTreeViewItem(InputControlLayout layout, string commonUsage) : base(layout.name) { m_Device = layout.name; m_Usage = commonUsage; if (commonUsage != null) { name += " (" + commonUsage + ")"; } id = name.GetHashCode(); m_SearchableName = InputControlPath.ToHumanReadableString(controlPathWithDevice); }
void OnSelection(ReorderableList list) { if (list.index < 0) { m_SelectedRow = null; return; } m_SelectedRow = (string)list.list[list.index]; m_NamesAndParams = InputControlLayout.ParseNameAndParameterList(m_Property.stringValue); m_SelectedParameterList = GetFieldsFromClass(); }
public void Setup(InternedString layout, InternedString variants, InputDeviceDescription deviceDescription = default) { m_LayoutCacheRef = InputControlLayout.CacheRef(); InstantiateLayout(layout, variants, new InternedString(), null); FinalizeControlHierarchy(); m_Device.m_Description = deviceDescription; m_Device.CallFinishSetupRecursive(); }
private InputControl InsertChildControl(InputControlLayout layout, InternedString variant, InputControl parent, ref bool haveChildrenUsingStateFromOtherControls, ref InputControlLayout.ControlItem controlItem) { var path = controlItem.name.ToString(); // First we need to find the immediate parent from the given path. var indexOfSlash = path.LastIndexOf('/'); if (indexOfSlash == -1) { throw new InvalidOperationException("InsertChildControl has to be called with a slash-separated path"); } Debug.Assert(indexOfSlash != 0, "Could not find slash in path"); var immediateParentPath = path.Substring(0, indexOfSlash); var immediateParent = InputControlPath.TryFindChild(parent, immediateParentPath); if (immediateParent == null) { throw new InvalidOperationException( $"Cannot find parent '{immediateParentPath}' of control '{controlItem.name}' in layout '{layout.name}'"); } var controlName = path.Substring(indexOfSlash + 1); if (controlName.Length == 0) { throw new InvalidOperationException( $"Path cannot end in '/' (control '{controlItem.name}' in layout '{layout.name}')"); } // Make room in the device's child array. var childStartIndex = immediateParent.m_ChildStartIndex; if (childStartIndex == default) { // First child of parent. childStartIndex = m_Device.m_ChildrenForEachControl.LengthSafe(); immediateParent.m_ChildStartIndex = childStartIndex; } var childIndex = childStartIndex + immediateParent.m_ChildCount; ShiftChildIndicesInHierarchyOneUp(m_Device, childIndex, immediateParent); ArrayHelpers.InsertAt(ref m_Device.m_ChildrenForEachControl, childIndex, null); ++immediateParent.m_ChildCount; // Insert the child. // NOTE: This may *add several* controls depending on the layout of the control we are inserting. // The children will be appended to the child array. var control = AddChildControl(layout, variant, immediateParent, ref haveChildrenUsingStateFromOtherControls, controlItem, childIndex, controlName); return(control); }
private static string FindControlLayoutRecursive(ref PathParser parser, InputControlLayout layout) { string currentResult = null; var controlCount = layout.controls.Count; for (var i = 0; i < controlCount; ++i) { if (layout.m_Controls[i].isModifyingChildControlByPath) { throw new NotImplementedException(); } ////TODO: shortcut the search if we have a match and there's no wildcards to consider // Skip control layout if it doesn't match. if (!ControlLayoutMatchesPathComponent(ref layout.m_Controls[i], ref parser)) { continue; } var controlLayoutName = layout.m_Controls[i].layout; // If there's more in the path, try to dive into children by jumping to the // control's layout. if (!parser.isAtEnd) { var childPathParser = parser; if (childPathParser.MoveToNextComponent()) { var childControlLayoutName = FindControlLayoutRecursive(ref childPathParser, controlLayoutName); if (childControlLayoutName != null) { if (currentResult != null && childControlLayoutName != currentResult) { return(null); } currentResult = childControlLayoutName; } } } else if (currentResult != null && controlLayoutName != currentResult) { return(null); } else { currentResult = controlLayoutName.ToString(); } } return(currentResult); }
public DeviceDropdownItem(InputControlLayout layout, string usage = null, bool searchable = true) : base(layout.m_DisplayName ?? ObjectNames.NicifyVariableName(layout.name)) { m_Device = layout.name; m_Usage = usage; if (usage != null) { name += " (" + usage + ")"; } id = name.GetHashCode(); m_Searchable = searchable; }
private static void ScanLayout(InputControlLayout layout) { var controls = layout.controls; for (var i = 0; i < controls.Count; ++i) { var control = controls[i]; // If it's not just a control modifying some inner child control, add control to all base // layouts as an optional control. // // NOTE: We're looking at layouts post-merging here. Means we have already picked up all the // controls present on the base. if (control.isFirstDefinedInThisLayout && !control.isModifyingExistingControl && !control.layout.IsEmpty()) { foreach (var baseLayout in layout.baseLayouts) { AddOptionalControlRecursive(baseLayout, ref control); } } // Collect unique usages and the layouts used with them. foreach (var usage in control.usages) { // Empty usages can occur for controls that want to reset inherited usages. if (string.IsNullOrEmpty(usage)) { continue; } var internedUsage = new InternedString(usage); var internedLayout = new InternedString(control.layout); if (!s_Usages.TryGetValue(internedUsage, out var layoutList)) { layoutList = new List <InternedString> { internedLayout }; s_Usages[internedUsage] = layoutList; } else { var layoutAlreadyInList = layoutList.Any(x => x == internedLayout); if (!layoutAlreadyInList) { layoutList.Add(internedLayout); } } } } }
private void OnCompositeParametersModified() { Debug.Assert(m_CompositeParameters != null); var path = m_PathProperty.stringValue; var nameAndParameters = InputControlLayout.ParseNameAndParameters(path); nameAndParameters.parameters = m_CompositeParameters.GetParameters(); m_PathProperty.stringValue = nameAndParameters.ToString(); OnPathModified(); }
void AddDeviceTreeItem(InputControlLayout layout, List <DeviceEntryForList> deviceList) { var entry = new DeviceEntryForList(); entry.name = layout.name; deviceList.Add(entry); foreach (var commonUsage in layout.commonUsages) { var entryWithUsage = new DeviceEntryForList(); entryWithUsage.name = layout.name; entryWithUsage.commonUsage = commonUsage; deviceList.Add(entryWithUsage); } }
private TreeViewItem AddControlLayoutItem(InputControlLayout layout, TreeViewItem parent, ref int id) { var item = AddChild(parent, layout.name, ref id); // Header. AddChild(item, "Type: " + layout.type.Name, 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.deviceMatcher.empty) { var node = AddChild(item, "Matching Devices", ref id); foreach (var pattern in layout.deviceMatcher.patterns) { AddChild(node, string.Format("{0} => \"{1}\"", 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); }
private void InitializeCompositeProperties() { // Find name of current composite. var path = m_PathProperty.stringValue; var compositeNameAndParameters = InputControlLayout.ParseNameAndParameters(path); var compositeName = compositeNameAndParameters.name; var compositeType = InputBindingComposite.s_Composites.LookupTypeRegistration(compositeName); // Collect all possible composite types. var selectedCompositeIndex = -1; var compositeTypeOptionsList = new List <GUIContent>(); var compositeTypeList = new List <string>(); var currentIndex = 0; foreach (var composite in InputBindingComposite.s_Composites.internedNames.Where(x => !InputBindingComposite.s_Composites.aliases.Contains(x)).OrderBy(x => x)) { if (InputBindingComposite.s_Composites.LookupTypeRegistration(composite) == compositeType) { selectedCompositeIndex = currentIndex; } var name = ObjectNames.NicifyVariableName(composite); compositeTypeOptionsList.Add(new GUIContent(name)); compositeTypeList.Add(composite); ++currentIndex; } // If the current composite type isn't a registered type, add it to the list as // an extra option. if (selectedCompositeIndex == -1) { selectedCompositeIndex = compositeTypeList.Count; compositeTypeOptionsList.Add(new GUIContent(ObjectNames.NicifyVariableName(compositeName))); compositeTypeList.Add(compositeName); } m_CompositeTypes = compositeTypeList.ToArray(); m_CompositeTypeOptions = compositeTypeOptionsList.ToArray(); m_SelectedCompositeType = selectedCompositeIndex; // Initialize parameters. m_CompositeParameters = new ParameterListView { onChange = OnCompositeParametersModified }; if (compositeType != null) { m_CompositeParameters.Initialize(compositeType, compositeNameAndParameters.parameters); } }
private void InitializeCompositePartProperties() { var currentCompositePart = m_BindingProperty.FindPropertyRelative("m_Name").stringValue; ////REVIEW: this makes a lot of assumptions about the serialized data based on the one property we've been given in the ctor // Determine the name of the current composite type that the part belongs to. var bindingArrayProperty = m_BindingProperty.GetArrayPropertyFromElement(); var partBindingIndex = InputActionSerializationHelpers.GetIndex(bindingArrayProperty, m_BindingProperty); var compositeBindingIndex = InputActionSerializationHelpers.GetCompositeStartIndex(bindingArrayProperty, partBindingIndex); if (compositeBindingIndex == -1) { return; } var compositeBindingProperty = bindingArrayProperty.GetArrayElementAtIndex(compositeBindingIndex); var compositePath = compositeBindingProperty.FindPropertyRelative("m_Path").stringValue; var compositeNameAndParameters = InputControlLayout.ParseNameAndParameters(compositePath); // Initialize option list from all parts available for the composite. var optionList = new List <GUIContent>(); var nameList = new List <string>(); var currentIndex = 0; var selectedPartNameIndex = -1; foreach (var partName in InputBindingComposite.GetPartNames(compositeNameAndParameters.name)) { if (partName.Equals(currentCompositePart, StringComparison.InvariantCultureIgnoreCase)) { selectedPartNameIndex = currentIndex; } var niceName = ObjectNames.NicifyVariableName(partName); optionList.Add(new GUIContent(niceName)); nameList.Add(partName); ++currentIndex; } // If currently selected part is not in list, add it as an option. if (selectedPartNameIndex == -1) { selectedPartNameIndex = nameList.Count; optionList.Add(new GUIContent(ObjectNames.NicifyVariableName(currentCompositePart))); nameList.Add(currentCompositePart); } m_CompositeParts = nameList.ToArray(); m_CompositePartOptions = optionList.ToArray(); m_SelectedCompositePart = selectedPartNameIndex; }
private void AddControlTreeItemsRecursive(InputControlLayout layout, AdvancedDropdownItem parent, string prefix, string deviceControlId, string commonUsage) { 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 ControlTreeViewItem(control, prefix, deviceControlId, commonUsage); if (LayoutMatchesExpectedControlLayoutFilter(control.layout)) { parent.AddChild(child); } var childLayout = EditorInputControlLayoutCache.TryGetLayout(control.layout); if (childLayout != null) { AddControlTreeItemsRecursive(childLayout, parent, child.controlPath, deviceControlId, commonUsage); } } // Add optional layouts for devices var optionalLayouts = EditorInputControlLayoutCache.GetOptionalControlsForLayout(layout.name); if (optionalLayouts.Any() && layout.isDeviceLayout) { var optionalGroup = new AdvancedDropdownItem("Optional"); foreach (var optionalLayout in optionalLayouts) { if (LayoutMatchesExpectedControlLayoutFilter(optionalLayout.layout)) { optionalGroup.AddChild(new OptionalControlTreeViewItem(optionalLayout, deviceControlId, commonUsage)); } } if (optionalGroup.children.Any()) { parent.AddChild(optionalGroup); } } }
private InputControl InsertChildControl(InputControlLayout layout, InternedString variant, InputControl parent, ref bool haveChildrenUsingStateFromOtherControls, ref InputControlLayout.ControlItem controlItem) { var path = controlItem.name.ToString(); // First we need to find the immediate parent from the given path. var indexOfSlash = path.LastIndexOf('/'); if (indexOfSlash == -1) { throw new ArgumentException("InsertChildControl has to be called with a slash-separated path", "path"); } Debug.Assert(indexOfSlash != 0); var immediateParentPath = path.Substring(0, indexOfSlash); var immediateParent = InputControlPath.TryFindChild(parent, immediateParentPath); if (immediateParent == null) { throw new Exception( string.Format("Cannot find parent '{0}' of control '{1}' in layout '{2}'", immediateParentPath, controlItem.name, layout.name)); } var controlName = path.Substring(indexOfSlash + 1); if (controlName.Length == 0) { throw new Exception( string.Format("Path cannot end in '/' (control '{0}' in layout '{1}')", controlItem.name, layout.name)); } // Make room in the device's child array. var childStartIndex = immediateParent.m_ChildrenReadOnly.m_StartIndex; var childIndex = childStartIndex + immediateParent.m_ChildrenReadOnly.m_Length; ArrayHelpers.InsertAt(ref m_Device.m_ChildrenForEachControl, childIndex, null); ++immediateParent.m_ChildrenReadOnly.m_Length; // Insert the child. var control = AddChildControl(layout, variant, immediateParent, null, ref haveChildrenUsingStateFromOtherControls, ref controlItem, ref childIndex, controlName); // Adjust indices of control's that have been shifted around by our insertion. ShiftChildIndicesInHierarchyOneUp(parent, childIndex); return(control); }
protected PropertiesReorderableList(SerializedProperty property, Action applyAction) { m_Property = property; m_Apply = applyAction; m_ListItems = new List <string>(); m_ListOptions = GetOptions(); m_EditableParametersForSelectedItem = new ParameterListView { onChange = OnParametersChanged }; m_ParametersForEachListItem = InputControlLayout.ParseNameAndParameterList(m_Property.stringValue) ?? new InputControlLayout.NameAndParameters[0]; foreach (var nameAndParams in m_ParametersForEachListItem) { m_ListItems.Add(nameAndParams.name); } m_ListView = new ReorderableList(m_ListItems, typeof(string)) { headerHeight = 3, onAddDropdownCallback = (rect, list) => { var menu = new GenericMenu(); foreach (var name in m_ListOptions.names) { menu.AddItem(new GUIContent(name), false, OnAddElement, name); } menu.ShowAsContext(); }, onRemoveCallback = list => { var index = list.index; list.list.RemoveAt(index); ArrayHelpers.EraseAt(ref m_ParametersForEachListItem, index); m_EditableParametersForSelectedItem.Clear(); m_Apply(); list.index = -1; }, onReorderCallbackWithDetails = (list, oldIndex, newIndex) => { MemoryHelpers.Swap(ref m_ParametersForEachListItem[oldIndex], ref m_ParametersForEachListItem[newIndex]); OnSelection(list); m_Apply(); }, onSelectCallback = OnSelection }; }
private int ResolveInteractions(string interactionString) { ////REVIEW: We're piggybacking off the processor parsing here as the two syntaxes are identical. Might consider //// moving the logic to a shared place. //// Alternatively, may split the paths. May help in getting rid of unnecessary allocations. var firstInteractionIndex = totalInteractionCount; if (!InputControlLayout.ParseNameAndParameterList(interactionString, ref m_Parameters)) { return(firstInteractionIndex); } for (var i = 0; i < m_Parameters.Count; ++i) { // Look up interaction. var type = InputInteraction.s_Interactions.LookupTypeRegistration(m_Parameters[i].name); if (type == null) { throw new Exception(string.Format( "No interaction with name '{0}' (mentioned in '{1}') has been registered", m_Parameters[i].name, interactionString)); } // Instantiate it. var interaction = Activator.CreateInstance(type) as IInputInteraction; if (interaction == null) { throw new Exception(string.Format("Interaction '{0}' is not an IInputInteraction", m_Parameters[i].name)); } // Pass parameters to it. InputDeviceBuilder.SetParameters(interaction, m_Parameters[i].parameters); // Add to list. var interactionStateCount = totalInteractionCount; ArrayHelpers.AppendWithCapacity(ref interactionStates, ref interactionStateCount, new InputActionMapState.InteractionState { phase = InputActionPhase.Waiting }); ArrayHelpers.AppendWithCapacity(ref interactions, ref totalInteractionCount, interaction); Debug.Assert(interactionStateCount == totalInteractionCount); } return(firstInteractionIndex); }
private bool ShouldIncludeDeviceLayout(InputControlLayout layout) { if (layout.hideInUI) { return(false); } // By default, if a device has no (usable) controls, we don't want it listed in the control picker // except if we're picking devices. if (!layout.controls.Any(x => LayoutMatchesExpectedControlLayoutFilter(x.layout)) && layout.controls.Any(x => true) && m_Mode != InputControlPicker.Mode.PickDevice) { return(false); } // If we have a device filter, see if we should ignore the device. if (m_ControlPathsToMatch != null && m_ControlPathsToMatch.Length > 0) { var matchesAnyInDeviceFilter = false; foreach (var entry in m_ControlPathsToMatch) { if (entry == layout.name || InputControlLayout.s_Layouts.IsBasedOn(new InternedString(entry), layout.name)) { matchesAnyInDeviceFilter = true; } else { ////FIXME: this also needs to work for full control paths and not just stuff like "<Gamepad>" var expectedLayout = InputControlPath.TryGetDeviceLayout(entry); if (!string.IsNullOrEmpty(expectedLayout) && (expectedLayout == layout.name || InputControlLayout.s_Layouts.IsBasedOn(new InternedString(expectedLayout), layout.name))) { matchesAnyInDeviceFilter = true; } } } if (!matchesAnyInDeviceFilter) { return(false); } } return(true); }
private void InitializeCompositeParameters() { m_CompositeParameters = new ParameterListView { onChange = OnCompositeParametersModified }; var path = m_PathProperty.stringValue; var nameAndParameters = InputControlLayout.ParseNameAndParameters(path); var compositeType = InputBindingComposite.s_Composites.LookupTypeRegistration(nameAndParameters.name); if (compositeType != null) { m_CompositeParameters.Initialize(compositeType, nameAndParameters.parameters); } }
private TreeViewItem BuildTreeForDevice(InputControlLayout layout, TreeViewItem parent, ref int id) { var deviceRoot = new Item { displayName = layout.name, id = id++, depth = parent.depth + 1, device = layout.name, layout = layout }; parent.AddChild(deviceRoot); BuildControlsRecursive(deviceRoot, layout, string.Empty, ref id); return(deviceRoot); }