public static void Process(InputRemoting receiver, Message msg) { var senderIndex = receiver.FindOrCreateSenderRecord(msg.participantId); // Remove devices added by remote. var devices = receiver.m_Senders[senderIndex].devices; if (devices != null) { foreach (var remoteDevice in devices) { var device = receiver.m_LocalManager.TryGetDeviceById(remoteDevice.localId); if (device != null) { receiver.m_LocalManager.RemoveDevice(device); } } } ////TODO: remove layouts added by remote ArrayHelpers.EraseAt(ref receiver.m_Senders, senderIndex); ////TODO: stop sending if last remote disconnects and StartSendingOnConnect is active }
public void OnPostprocessBuild(BuildReport report) { if (m_SettingsAddedToPreloadedAssets == null) { return; } var wasDirty = IsPlayerSettingsDirty(); // Revert back to original state. var preloadedAssets = PlayerSettings.GetPreloadedAssets(); var index = preloadedAssets.IndexOfReference <Object, Object>(m_SettingsAddedToPreloadedAssets); if (index != -1) { ArrayHelpers.EraseAt(ref preloadedAssets, index); PlayerSettings.SetPreloadedAssets(preloadedAssets); } m_SettingsAddedToPreloadedAssets = null; if (!wasDirty) { ClearPlayerSettingsDirtyFlag(); } }
private void InitializeModifierListView() { m_ModifierListView = new ReorderableList(m_Modifiers, typeof(InputTemplate.NameAndParameters)); m_ModifierListView.drawHeaderCallback = (rect) => EditorGUI.LabelField(rect, Contents.modifiers); m_ModifierListView.drawElementCallback = (rect, index, isActive, isFocused) => { ////TODO: parameters EditorGUI.LabelField(rect, m_Modifiers[index].name); }; m_ModifierListView.onAddDropdownCallback = (rect, list) => { var menu = new GenericMenu(); for (var i = 0; i < m_ModifierChoices.Length; ++i) { menu.AddItem(m_ModifierChoices[i], false, AddModifier, m_ModifierChoices[i].text); } menu.ShowAsContext(); }; m_ModifierListView.onRemoveCallback = (list) => { ArrayHelpers.EraseAt(ref m_Modifiers, list.index); ApplyModifiers(); }; }
private void OnDeleteControlScheme() { Debug.Assert(m_SelectedControlSchemeIndex >= 0, "Control scheme must be selected"); var name = m_ControlSchemes[m_SelectedControlSchemeIndex].name; var bindingGroup = m_ControlSchemes[m_SelectedControlSchemeIndex].bindingGroup; // Ask for confirmation. if (!EditorUtility.DisplayDialog("Delete scheme?", $"Do you want to delete control scheme '{name}'?", "Delete", "Cancel")) { return; } ArrayHelpers.EraseAt(ref m_ControlSchemes, m_SelectedControlSchemeIndex); m_SelectedControlSchemeIndex = -1; m_SelectedSchemeDeviceRequirementNames = null; if (m_SelectedDeviceRequirementIndex >= 0) { m_SelectedDeviceRequirementIndex = -1; onSelectedDeviceChanged?.Invoke(); } onControlSchemesChanged?.Invoke(); onSelectedSchemeChanged?.Invoke(); onControlSchemeDeleted?.Invoke(name, bindingGroup); }
public void OnGUI() { if (m_EditableParametersForEachListItem == null || m_EditableParametersForEachListItem.Length == 0) { using (var scope = new EditorGUI.DisabledScope(true)) { EditorGUI.indentLevel++; EditorGUILayout.LabelField($"No {itemName}s have been added."); EditorGUI.indentLevel--; } } else { for (var i = 0; i < m_EditableParametersForEachListItem.Length; i++) { var editableParams = m_EditableParametersForEachListItem[i]; EditorGUILayout.BeginHorizontal(); if (editableParams.hasUIToShow) { editableParams.visible = EditorGUILayout.Foldout(editableParams.visible, editableParams.name, Styles.s_FoldoutStyle); } else { GUILayout.Space(16); EditorGUILayout.LabelField(editableParams.name, EditorStyles.boldLabel); } GUILayout.FlexibleSpace(); using (var scope = new EditorGUI.DisabledScope(i == 0)) { if (GUILayout.Button(m_UpButton, Styles.s_UpDownButtonStyle)) { SwapEntry(i, i - 1); } } using (var scope = new EditorGUI.DisabledScope(i == m_EditableParametersForEachListItem.Length - 1)) { if (GUILayout.Button(m_DownButton, Styles.s_UpDownButtonStyle)) { SwapEntry(i, i + 1); } } if (GUILayout.Button(m_DeleteButton, EditorStyles.label)) { ArrayHelpers.EraseAt(ref m_ParametersForEachListItem, i); ArrayHelpers.EraseAt(ref m_EditableParametersForEachListItem, i); m_Apply(); GUIUtility.ExitGUI(); } EditorGUILayout.EndHorizontal(); if (editableParams.visible) { EditorGUI.indentLevel++; editableParams.OnGUI(); EditorGUI.indentLevel--; } GUIHelpers.DrawLineSeparator(); } } }
public void RemoveControlScheme(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } ArrayHelpers.EraseAt(ref m_ControlSchemes, GetControlSchemeIndex(name)); }
/// <summary> /// Remove the given action from its <see cref="InputActionMap"/>. /// </summary> /// <param name="action">An input action that is part of an <see cref="InputActionMap"/>.</param> /// <exception cref="ArgumentNullException"><paramref name="action"/> is <c>null</c>.</exception> /// <exception cref="ArgumentException"><paramref name="action"/> is part of an <see cref="InputActionMap"/> /// that has at least one enabled action -or- <paramref name="action"/> is a standalone action /// that is not part of an <see cref="InputActionMap"/> and thus cannot be removed from anything.</exception> /// <remarks> /// After removal, the action's <see cref="InputAction.actionMap"/> will be set to <c>null</c> /// and the action will effectively become a standalone action that is not associated with /// any action map. Bindings on the action will be preserved. On the action map, the bindings /// for the action will be removed. /// </remarks> /// <seealso cref="AddAction"/> public static void RemoveAction(this InputAction action) { if (action == null) { throw new ArgumentNullException(nameof(action)); } var actionMap = action.actionMap; if (actionMap == null) { throw new ArgumentException( $"Action '{action}' does not belong to an action map; nowhere to remove from", nameof(action)); } if (actionMap.enabled) { throw new ArgumentException($"Cannot remove action '{action}' while its action map is enabled"); } var bindingsForAction = action.bindings.ToArray(); var index = ArrayHelpers.IndexOfReference(actionMap.m_Actions, action); Debug.Assert(index != -1, "Could not find action in map"); ArrayHelpers.EraseAt(ref actionMap.m_Actions, index); action.m_ActionMap = null; action.m_SingletonActionBindings = bindingsForAction; actionMap.ClearPerActionCachedBindingData(); // Remove bindings to action from map. var newActionMapBindingCount = actionMap.m_Bindings.Length - bindingsForAction.Length; if (newActionMapBindingCount == 0) { actionMap.m_Bindings = null; } else { var newActionMapBindings = new InputBinding[newActionMapBindingCount]; var oldActionMapBindings = actionMap.m_Bindings; var bindingIndex = 0; for (var i = 0; i < oldActionMapBindings.Length; ++i) { var binding = oldActionMapBindings[i]; if (bindingsForAction.IndexOf(b => b == binding) == -1) { newActionMapBindings[bindingIndex++] = binding; } } actionMap.m_Bindings = newActionMapBindings; } }
public void Erase() { ArrayHelpers.EraseAt(ref m_ActionMap.m_Bindings, m_BindingIndex); m_ActionMap.ClearPerActionCachedBindingData(); // We have switched to a different binding array. For singleton actions, we need to // sync up the reference that the action itself has. if (m_ActionMap.m_SingletonAction != null) { m_ActionMap.m_SingletonAction.m_SingletonActionBindings = m_ActionMap.m_Bindings; } }
private void OnDisconnected(int id) { if (m_ConnectedIds == null || !ArrayHelpers.Contains(m_ConnectedIds, id)) { return; } ArrayHelpers.EraseAt(ref m_ConnectedIds, id); SendToSubscribers(InputRemoting.MessageType.Disconnect, new MessageEventArgs { playerId = id }); }
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 }; }
/// <summary> /// Remove the control scheme with the given name from the asset. /// </summary> /// <param name="asset">Asset to remove the control scheme from.</param> /// <param name="name">Name of the control scheme. Matching is case-insensitive.</param> /// <exception cref="ArgumentNullException"><paramref name="asset"/> is null -or- <paramref name="name"/> /// is <c>null</c> or empty.</exception> /// <remarks> /// If no control scheme with the given name can be found, the method does nothing. /// </remarks> public static void RemoveControlScheme(this InputActionAsset asset, string name) { if (asset == null) { throw new ArgumentNullException(nameof(asset)); } if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(nameof(name)); } var index = asset.FindControlSchemeIndex(name); if (index != -1) { ArrayHelpers.EraseAt(ref asset.m_ControlSchemes, index); } }
private void InitializeInteractionListView() { m_InteractionListView = new ReorderableList(m_Interactions, typeof(InputControlLayout.NameAndParameters)); m_InteractionListView.drawHeaderCallback = rect => EditorGUI.LabelField(rect, Contents.interactions); m_InteractionListView.drawElementCallback = (rect, index, isActive, isFocused) => { ////TODO: parameters EditorGUI.LabelField(rect, m_Interactions[index].name); }; m_InteractionListView.onAddDropdownCallback = (rect, list) => { var menu = new GenericMenu(); for (var i = 0; i < m_InteractionChoices.Length; ++i) { menu.AddItem(m_InteractionChoices[i], false, AddInteraction, m_InteractionChoices[i].text); } menu.ShowAsContext(); }; m_InteractionListView.onRemoveCallback = (list) => { var indexToRemove = list.index; if (indexToRemove == m_Interactions.Length - 1) { --list.index; } ArrayHelpers.EraseAt(ref m_Interactions, indexToRemove); if (m_Interactions == null) { m_Interactions = new InputControlLayout.NameAndParameters[0]; } list.list = m_Interactions; ApplyInteractions(); }; }
public void RemoveRemoteDevices(int participantId) { var senderIndex = FindOrCreateSenderRecord(participantId); // Remove devices added by remote. var devices = m_Senders[senderIndex].devices; if (devices != null) { foreach (var remoteDevice in devices) { var device = m_LocalManager.TryGetDeviceById(remoteDevice.localId); if (device != null) { m_LocalManager.RemoveDevice(device); } } } ////TODO: remove layouts added by remote ArrayHelpers.EraseAt(ref m_Senders, senderIndex); }
public static void ReplaceBindingGroup(SerializedObject asset, string oldBindingGroup, string newBindingGroup, bool deleteOrphanedBindings = false) { var mapArrayProperty = asset.FindProperty("m_ActionMaps"); var mapCount = mapArrayProperty.arraySize; for (var k = 0; k < mapCount; ++k) { var actionMapProperty = mapArrayProperty.GetArrayElementAtIndex(k); var bindingsArrayProperty = actionMapProperty.FindPropertyRelative("m_Bindings"); var bindingsCount = bindingsArrayProperty.arraySize; for (var i = 0; i < bindingsCount; ++i) { var bindingProperty = bindingsArrayProperty.GetArrayElementAtIndex(i); var groupsProperty = bindingProperty.FindPropertyRelative("m_Groups"); var groups = groupsProperty.stringValue; // Ignore bindings not belonging to any control scheme. if (string.IsNullOrEmpty(groups)) { continue; } var groupsArray = groups.Split(InputBinding.Separator); var numGroups = groupsArray.LengthSafe(); var didRename = false; for (var n = 0; n < numGroups; ++n) { if (string.Compare(groupsArray[n], oldBindingGroup, StringComparison.InvariantCultureIgnoreCase) != 0) { continue; } if (string.IsNullOrEmpty(newBindingGroup)) { ArrayHelpers.EraseAt(ref groupsArray, n); --n; --numGroups; } else { groupsArray[n] = newBindingGroup; } didRename = true; } if (!didRename) { continue; } if (groupsArray != null) { groupsProperty.stringValue = string.Join(InputBinding.kSeparatorString, groupsArray); } else { if (deleteOrphanedBindings) { // Binding no long belongs to any binding group. Delete it. bindingsArrayProperty.DeleteArrayElementAtIndex(i); --i; --bindingsCount; } else { groupsProperty.stringValue = string.Empty; } } } } }
public override void OnGUI(string searchContext) { if (m_Settings == null) { InitializeWithCurrentSettings(); } EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); var selectedSettingsAsset = EditorGUILayout.Popup(m_CurrentSelectedInputSettingsAsset, m_AvailableSettingsAssetsOptions, EditorStyles.toolbarPopup); if (selectedSettingsAsset != m_CurrentSelectedInputSettingsAsset) { // If we selected an asset and the current settings are not coming from an asset, // remove the "<No Asset>" entry we added to the dropdown. if (selectedSettingsAsset != 0 && m_AvailableInputSettingsAssets[m_CurrentSelectedInputSettingsAsset] == "<No Asset>") { ArrayHelpers.EraseAt(ref m_AvailableInputSettingsAssets, m_CurrentSelectedInputSettingsAsset); } m_CurrentSelectedInputSettingsAsset = selectedSettingsAsset; var settings = AssetDatabase.LoadAssetAtPath <InputSettings>( m_AvailableInputSettingsAssets[selectedSettingsAsset]); // Install. This will automatically cause us to re-initialize through InputSystem.onSettingsChange. InputSystem.settings = settings; } // Style can only be initialized after skin has been initialized. Settings providers are // pulled up earlier than that so we do it lazily from here. if (m_NewAssetButtonStyle == null) { m_NewAssetButtonStyle = new GUIStyle("toolbarButton"); m_NewAssetButtonStyle.fixedWidth = 40; } if (GUILayout.Button(m_NewAssetButtonText, m_NewAssetButtonStyle)) { CreateNewSettingsAsset(); } GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); if (m_AvailableInputSettingsAssets[m_CurrentSelectedInputSettingsAsset] == "<No Asset>") { EditorGUILayout.HelpBox("Input settings can only be edited when stored in an asset.\n\n" + "Choose an existing asset (if any) from the dropdown or create a new asset by pressing the 'New' button. " + "Input settings can be placed anywhere in your project.", MessageType.Info); } EditorGUILayout.HelpBox( "Please note that the new input system is still under development and not all features are fully functional or stable yet.\n\n" + "For more information, visit https://github.com/Unity-Technologies/InputSystem or https://forum.unity.com/forums/new-input-system.103/.", MessageType.Warning); EditorGUILayout.Space(); EditorGUILayout.Separator(); EditorGUILayout.Space(); Debug.Assert(m_Settings != null); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_UpdateMode); var updateMode = (InputSettings.UpdateMode)m_UpdateMode.intValue; if (updateMode == InputSettings.UpdateMode.ProcessEventsInBothFixedAndDynamicUpdate) { // Choosing action update mode only makes sense if we have an ambiguous situation, i.e. // when we have both dynamic and fixed updates in the picture. ////TODO: enable when action update mode is properly sorted //EditorGUILayout.PropertyField(m_ActionUpdateMode); } ////TODO: enable when backported //EditorGUILayout.PropertyField(m_TimesliceEvents); EditorGUILayout.PropertyField(m_RunInBackground); EditorGUILayout.PropertyField(m_FilterNoiseOnCurrent); EditorGUILayout.PropertyField(m_CompensateForScreenOrientation); EditorGUILayout.Space(); EditorGUILayout.Separator(); EditorGUILayout.Space(); EditorGUILayout.PropertyField(m_DefaultDeadzoneMin); EditorGUILayout.PropertyField(m_DefaultDeadzoneMax); EditorGUILayout.PropertyField(m_DefaultButtonPressPoint); EditorGUILayout.PropertyField(m_DefaultTapTime); EditorGUILayout.PropertyField(m_DefaultSlowTapTime); EditorGUILayout.PropertyField(m_DefaultHoldTime); EditorGUILayout.Space(); EditorGUILayout.Separator(); EditorGUILayout.Space(); EditorGUILayout.HelpBox("Leave 'Supported Devices' empty if you want the input system to support all input devices it can recognize. If, however, " + "you are only interested in a certain set of devices, adding them here will narrow the scope of what's presented in the editor " + "and avoid picking up input from devices not relevant to the project.", MessageType.None); m_SupportedDevices.DoLayoutList(); if (EditorGUI.EndChangeCheck()) { Apply(); } }
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 }; }