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); }
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(); }
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); }
public PropertiesReorderableList(SerializedProperty property, Action applyAction) { m_Property = property; m_Apply = applyAction; m_ListOptions = GetOptions(); m_ListView = new ReorderableList(new List <string>(), typeof(string)); m_NamesAndParams = InputControlLayout.ParseNameAndParameterList(m_Property.stringValue); if (m_NamesAndParams == null) { m_NamesAndParams = new InputControlLayout.NameAndParameters[0]; } foreach (var nameAndParams in m_NamesAndParams) { m_ListView.list.Add(nameAndParams.name); } m_ListView.headerHeight = 3; m_ListView.onAddDropdownCallback = (rect, list) => { var menu = new GenericMenu(); for (var i = 0; i < m_ListOptions.names.Count(); ++i) { menu.AddItem(new GUIContent(m_ListOptions.names.ElementAt(i)), false, AddElement, m_ListOptions.names.ElementAt(i)); } menu.ShowAsContext(); }; m_ListView.onRemoveCallback = (list) => { list.list.RemoveAt(list.index); m_Apply(); list.index = -1; }; m_ListView.onReorderCallback = list => { m_Apply(); }; m_ListView.onSelectCallback = OnSelection; }
public ModifyPopupWindow(SerializedProperty bindingProperty) { m_FlagsProperty = bindingProperty.FindPropertyRelative("m_Flags"); m_InteractionsProperty = bindingProperty.FindPropertyRelative("m_Interactions"); m_Flags = (InputBinding.Flags)m_FlagsProperty.intValue; var interactions = InputSystem.ListInteractions().ToList(); interactions.Sort(); m_InteractionChoices = interactions.Select(x => new GUIContent(x)).ToArray(); var interactionString = m_InteractionsProperty.stringValue; if (!string.IsNullOrEmpty(interactionString)) { m_Interactions = InputControlLayout.ParseNameAndParameterList(interactionString); } else { m_Interactions = new InputControlLayout.NameAndParameters[0]; } InitializeInteractionListView(); }
////TODO: move this out into a general routine that can take a path and construct a display name private static GUIContent GetContentForPath(string path, string interactions, InputBinding.Flags flags) { const int kUsageNameGroup = 1; const int kDeviceNameGroup = 1; const int kDeviceUsageGroup = 3; const int kControlPathGroup = 4; ////TODO: nuke the regex stuff in here if (s_UsageRegex == null) { s_UsageRegex = new Regex("\\*/{([A-Za-z0-9]+)}"); } if (s_ControlRegex == null) { s_ControlRegex = new Regex("<([A-Za-z0-9:\\-]+)>({([A-Za-z0-9]+)})?/([A-Za-z0-9]+(/[A-Za-z0-9]+)*)"); } var text = path; var usageMatch = s_UsageRegex.Match(path); if (usageMatch.Success) { text = usageMatch.Groups[kUsageNameGroup].Value; } else { var controlMatch = s_ControlRegex.Match(path); if (controlMatch.Success) { var device = controlMatch.Groups[kDeviceNameGroup].Value; var deviceUsage = controlMatch.Groups[kDeviceUsageGroup].Value; var control = controlMatch.Groups[kControlPathGroup].Value; ////TODO: would be nice to include layout name to print something like "Gamepad A Button" instead of "Gamepad A" (or whatever) if (!string.IsNullOrEmpty(deviceUsage)) { text = string.Format("{0} {1} {2}", deviceUsage, device, control); } else { text = string.Format("{0} {1}", device, control); } } } ////REVIEW: would be nice to have icons for these // Show interactions. if (!string.IsNullOrEmpty(interactions)) { var interactionList = InputControlLayout.ParseNameAndParameterList(interactions); var interactionString = string.Join(" OR ", interactionList.Select(x => x.name).ToArray()); text = string.Format("{0} {1}", interactionString, text); } ////TODO: this looks ugly and not very obvious; find a better way // Show if linked with previous binding. if ((flags & InputBinding.Flags.ThisAndPreviousCombine) == InputBinding.Flags.ThisAndPreviousCombine) { text = "AND " + text; } return(new GUIContent(text)); }
protected PropertiesReorderableList(SerializedProperty property, Action applyAction, string expectedControlLayout) { 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]; m_ExpectedControlLayout = expectedControlLayout; foreach (var nameAndParams in m_ParametersForEachListItem) { var name = ObjectNames.NicifyVariableName(nameAndParams.name); ////REVIEW: finding this kind of stuff should probably have better support globally on the asset; e.g. some //// notification that pops up and allows fixing all occurrences in one click // Find out if we still support this option and indicate it in the list, if we don't. if (m_ListOptions.LookupTypeRegistration(new InternedString(nameAndParams.name)) == null) { name += " (Obsolete)"; } m_ListItems.Add(name); } m_ListView = new ReorderableList(m_ListItems, typeof(string)) { headerHeight = 3, onAddDropdownCallback = (rect, list) => { Type expectedValueType = null; if (!string.IsNullOrEmpty(m_ExpectedControlLayout)) { expectedValueType = EditorInputControlLayoutCache.GetValueType(m_ExpectedControlLayout); } // Add only original names to the menu and not aliases. var menu = new GenericMenu(); foreach (var name in m_ListOptions.internedNames.Where(x => !m_ListOptions.aliases.Contains(x)).OrderBy(x => x.ToString())) { // Skip if not compatible with value type. if (expectedValueType != null) { var type = m_ListOptions.LookupTypeRegistration(name); var valueType = GetValueType(type); if (valueType != null && !expectedValueType.IsAssignableFrom(valueType)) { continue; } } var niceName = ObjectNames.NicifyVariableName(name); menu.AddItem(new GUIContent(niceName), false, OnAddElement, name.ToString()); } 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 }; }
////TODO: move this out into a general routine that can take a path and construct a display name private GUIContent GetContentForPath(string path, string interactions, InputBinding.Flags flags) { const int kUsageNameGroup = 1; const int kDeviceNameGroup = 1; const int kDeviceUsageGroup = 3; const int kControlPathGroup = 4; if (s_UsageRegex == null) { s_UsageRegex = new Regex("\\*/{([A-Za-z0-9]+)}"); } if (s_ControlRegex == null) { s_ControlRegex = new Regex("<([A-Za-z0-9:\\-]+)>({([A-Za-z0-9]+)})?/([A-Za-z0-9]+(/[A-Za-z0-9]+)*)"); } var text = path; ////TODO: make this less GC heavy ////TODO: prettify control names (e.g. "rightTrigger" should read "Right Trigger"); have explicit display names? ////REVIEW: This stuff here should really be based on general display functionality for controls //// which should be available to game code in just the same way for on-screen display //// purposes var usageMatch = s_UsageRegex.Match(path); if (usageMatch.Success) { text = usageMatch.Groups[kUsageNameGroup].Value; } else { var controlMatch = s_ControlRegex.Match(path); if (controlMatch.Success) { var device = controlMatch.Groups[kDeviceNameGroup].Value; var deviceUsage = controlMatch.Groups[kDeviceUsageGroup].Value; var control = controlMatch.Groups[kControlPathGroup].Value; ////TODO: would be nice to include layout name to print something like "Gamepad A Button" instead of "Gamepad A" (or whatever) if (!string.IsNullOrEmpty(deviceUsage)) { text = string.Format("{0} {1} {2}", deviceUsage, device, control); } else { text = string.Format("{0} {1}", device, control); } } } ////REVIEW: would be nice to have icons for these // Show interactions. if (!string.IsNullOrEmpty(interactions)) { var interactionList = InputControlLayout.ParseNameAndParameterList(interactions); var interactionString = string.Join(" OR ", interactionList.Select(x => x.name).ToArray()); text = string.Format("{0} {1}", interactionString, text); } ////TODO: this looks ugly and not very obvious; find a better way // Show if linked with previous binding. if ((flags & InputBinding.Flags.ThisAndPreviousCombine) == InputBinding.Flags.ThisAndPreviousCombine) { text = "AND " + text; } return(new GUIContent(text)); }