////TODO: move this out into a general routine that can take a path and construct a display name private GUIContent GetContentForPath(string path, string modifiers, InputBinding.Flags flags) { 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]+)*)"); } 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[1].Value; } else { var controlMatch = s_ControlRegex.Match(path); if (controlMatch.Success) { var device = controlMatch.Groups[1].Value; var control = controlMatch.Groups[2].Value; ////TODO: would be nice to include template name to print something like "Gamepad A Button" instead of "Gamepad A" (or whatever) text = string.Format("{0} {1}", device, control); } } ////REVIEW: would be nice to have icons for these // Show modifiers. if (!string.IsNullOrEmpty(modifiers)) { var modifierList = InputTemplate.ParseNameAndParameterList(modifiers); var modifierString = string.Join(" OR ", modifierList.Select(x => x.name).ToArray()); text = string.Format("{0} {1}", modifierString, 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)); }
private static int ResolveModifiers(string modifierString, ref List <ModifierState> modifiers) { ////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 firstModifierIndex = modifiers != null ? modifiers.Count : 0; ////TODO: get rid of the extra array allocations here var list = InputTemplate.ParseNameAndParameterList(modifierString); for (var i = 0; i < list.Length; ++i) { // Look up modifier. var type = InputSystem.TryGetModifier(list[i].name); if (type == null) { throw new Exception(string.Format( "No modifier with name '{0}' (mentioned in '{1}') has been registered", list[i].name, modifierString)); } // Instantiate it. var modifier = Activator.CreateInstance(type) as IInputActionModifier; if (modifier == null) { throw new Exception(string.Format("Modifier '{0}' is not an IInputActionModifier", list[i].name)); } // Pass parameters to it. InputControlSetup.SetParameters(modifier, list[i].parameters); // Add to list. if (modifiers == null) { modifiers = new List <ModifierState>(); } modifiers.Add(new ModifierState { modifier = modifier, phase = InputAction.Phase.Waiting }); } return(firstModifierIndex); }
public ModifyPopupWindow(SerializedProperty bindingProperty) { m_FlagsProperty = bindingProperty.FindPropertyRelative("flags"); m_ModifiersProperty = bindingProperty.FindPropertyRelative("modifiers"); m_Flags = (InputBinding.Flags)m_FlagsProperty.intValue; var modifiers = InputSystem.ListModifiers().ToList(); modifiers.Sort(); m_ModifierChoices = modifiers.Select(x => new GUIContent(x)).ToArray(); var modifierString = m_ModifiersProperty.stringValue; if (!string.IsNullOrEmpty(modifierString)) { m_Modifiers = InputTemplate.ParseNameAndParameterList(modifierString); } else { m_Modifiers = new InputTemplate.NameAndParameters[0]; //Array.Empty<InputTemplate.NameAndParameters>(); } InitializeModifierListView(); }