diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs index c980613c17..4705cb16cf 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs @@ -321,7 +321,7 @@ void OnEditEnd() var boolValue = parameter.value.value.ToBoolean(); var field = new Toggle(label.text) { value = boolValue }; field.RegisterValueChangedCallback(evt => OnValueChanged(ref parameter, evt.newValue, closedIndex)); - field.RegisterCallback(_ => OnEditEnd()); + field.RegisterValueChangedCallback(_ => OnEditEnd()); root.Add(field); } } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs index 39c62e9943..5918eab66d 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs @@ -69,6 +69,20 @@ public static Command AddBinding() }; } + public static Command AddComposite(string compositeName) + { + return (in InputActionsEditorState state) => + { + var action = Selectors.GetSelectedAction(state)?.wrappedProperty; + var map = Selectors.GetSelectedActionMap(state)?.wrappedProperty; + var compositeType = InputBindingComposite.s_Composites.LookupTypeRegistration(compositeName); + var composite = InputActionSerializationHelpers.AddCompositeBinding(action, map, compositeName, compositeType); + var index = new SerializedInputBinding(composite).indexOfBinding; + state.serializedObject.ApplyModifiedProperties(); + return state.With(selectedBindingIndex: index, selectionType: SelectionType.Binding); + }; + } + public static Command DeleteActionMap(int actionMapIndex) { return (in InputActionsEditorState state) => diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs index 485a8545b0..2f1b345407 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs @@ -29,7 +29,7 @@ public ActionMapsView(VisualElement root, StateContainer stateContainer) treeViewItem.DeleteCallback = _ => DeleteActionMap(i); treeViewItem.OnDeleteItem += treeViewItem.DeleteCallback; - ContextMenu.GetContextMenuForActionMapItem(treeViewItem, m_ListView); + ContextMenu.GetContextMenuForActionMapItem(treeViewItem); }; m_ListView.makeItem = () => new InputActionsTreeViewItem(); m_ListView.unbindItem = (element, i) => diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs index f2e9ac1ad3..a709074d70 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs @@ -11,11 +11,13 @@ namespace UnityEngine.InputSystem.Editor internal class ActionPropertiesView : ViewBase<(SerializedInputAction?, List)> { private readonly VisualElement m_Root; + private readonly Foldout m_ParentFoldout; - public ActionPropertiesView(VisualElement root, StateContainer stateContainer) + public ActionPropertiesView(VisualElement root, Foldout foldout, StateContainer stateContainer) : base(stateContainer) { m_Root = root; + m_ParentFoldout = foldout; // TODO: Consider IEquatable and how to compare selector data CreateSelector(Selectors.GetSelectedAction, @@ -31,6 +33,8 @@ public override void RedrawUI((SerializedInputAction ? , List) viewState { if (!viewState.Item1.HasValue) return; + + m_ParentFoldout.text = "Action"; var inputAction = viewState.Item1.Value; m_Root.Clear(); diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs index 6111daac4a..e7477e03b6 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs @@ -37,9 +37,10 @@ public ActionsTreeView(VisualElement root, StateContainer stateContainer) var treeViewItem = (InputActionsTreeViewItem)e; treeViewItem.DeleteCallback = _ => DeleteItem(item); treeViewItem.OnDeleteItem += treeViewItem.DeleteCallback; - - if (item.isAction || item.isComposite) - ContextMenu.GetContextMenuForActionOrCompositeItem(treeViewItem, m_ActionsTreeView, i); + if (item.isComposite) + ContextMenu.GetContextMenuForCompositeItem(treeViewItem, i); + else if (item.isAction) + ContextMenu.GetContextMenuForActionItem(treeViewItem, i); else ContextMenu.GetContextMenuForBindingItem(treeViewItem); @@ -183,22 +184,28 @@ private void RenameNewAction(int id) if (!m_RenameOnActionAdded || id == -1) return; m_ActionsTreeView.ScrollToItemById(id); - var treeViewItem = m_ActionsTreeView.GetRootElementForId(id).Q(); - treeViewItem.FocusOnRenameTextField(); + var treeViewItem = m_ActionsTreeView.GetRootElementForId(id)?.Q(); + treeViewItem?.FocusOnRenameTextField(); } - private void AddAction() + internal void AddAction() { Dispatch(Commands.AddAction()); m_RenameOnActionAdded = true; } - private void AddBinding(string actionName) + internal void AddBinding(string actionName) { Dispatch(Commands.SelectAction(actionName)); Dispatch(Commands.AddBinding()); } + internal void AddComposite(string actionName, string compositeType) + { + Dispatch(Commands.SelectAction(actionName)); + Dispatch(Commands.AddComposite(compositeType)); + } + private void DeleteItem(ActionOrBindingData data) { if (data.isAction) @@ -347,7 +354,7 @@ private static string GetHumanReadableBindingName(SerializedInputBinding seriali internal static string GetHumanReadableCompositeName(SerializedInputBinding binding) { return $"{ObjectNames.NicifyVariableName(binding.name)}: " + - $"{InputControlPath.ToHumanReadableString(binding.path)}"; + $"{GetHumanReadableBindingName(binding)}"; } private static string GetControlLayout(string path) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs index d87fdbcbfb..688b098fab 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs @@ -41,6 +41,8 @@ public override void RedrawUI(ViewState viewState) var binding = viewState.selectedBinding; if (!binding.HasValue) return; + + m_ParentFoldout.text = "Binding"; if (binding.Value.isComposite) { m_ParentFoldout.text = "Composite"; @@ -53,8 +55,6 @@ public override void RedrawUI(ViewState viewState) } else { - m_ParentFoldout.text = "Binding"; - var controlPathEditor = new InputControlPathEditor(viewState.selectedBindingPath, new InputControlPickerState(), () => { Dispatch(Commands.ApplyModifiedProperties()); }); diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs index f3a4a86f0b..9fcbc75687 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs @@ -1,53 +1,68 @@ #if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; using UnityEngine.UIElements; namespace UnityEngine.InputSystem.Editor { - internal static partial class ContextMenu + internal static class ContextMenu { private static readonly string rename_String = "Rename"; private static readonly string delete_String = "Delete"; - public static void GetContextMenuForActionMapItem(InputActionsTreeViewItem targetElement, ListView listView) + + private static readonly string add_Action_String = "Add Action"; + private static readonly string add_Binding_String = "Add Binding"; + private static readonly string add_positiveNegative_Binding_String = "Add Positive\\Negative Binding"; + private static readonly string add_oneModifier_Binding_String = "Add Binding With One Modifier"; + private static readonly string add_twoModifier_Binding_String = "Add Binding With Two Modifiers"; + public static void GetContextMenuForActionMapItem(InputActionsTreeViewItem treeViewItem) { var _ = new ContextualMenuManipulator(menuEvent => { - menuEvent.menu.AppendAction(rename_String, action => - { - listView.SetSelection(listView.itemsSource.IndexOf(targetElement.label.text)); - targetElement.FocusOnRenameTextField(); - }); - AppendDeleteAction(menuEvent, targetElement); - }) { target = targetElement }; + menuEvent.menu.AppendAction(add_Action_String, _ => InputActionViewsControlsHolder.CreateAction.Invoke(treeViewItem)); + menuEvent.menu.AppendSeparator(); + menuEvent.menu.AppendAction(rename_String, _ => InputActionViewsControlsHolder.RenameActionMap.Invoke(treeViewItem)); + AppendDeleteAction(menuEvent, treeViewItem); + }) { target = treeViewItem }; } - public static void GetContextMenuForActionOrCompositeItem(InputActionsTreeViewItem targetElement, TreeView treeView, int index) + public static void GetContextMenuForActionItem(InputActionsTreeViewItem treeViewItem, int index) { var _ = new ContextualMenuManipulator(menuEvent => { - menuEvent.menu.AppendAction(rename_String, action => - { - treeView.SetSelection(index); - targetElement.FocusOnRenameTextField(); - }); - AppendDeleteAction(menuEvent, targetElement); - }) { target = targetElement }; + menuEvent.menu.AppendAction(add_Binding_String, _ => InputActionViewsControlsHolder.AddBinding.Invoke(treeViewItem)); + menuEvent.menu.AppendAction(add_positiveNegative_Binding_String, _ => InputActionViewsControlsHolder.AddCompositePositivNegativModifier.Invoke(treeViewItem)); + menuEvent.menu.AppendAction(add_oneModifier_Binding_String, _ => InputActionViewsControlsHolder.AddCompositeOneModifier.Invoke(treeViewItem)); + menuEvent.menu.AppendAction(add_twoModifier_Binding_String, _ => InputActionViewsControlsHolder.AddCompositeTwoModifier.Invoke(treeViewItem)); + menuEvent.menu.AppendSeparator(); + AppendRenameAction(menuEvent, index, treeViewItem); + AppendDeleteAction(menuEvent, treeViewItem); + }) { target = treeViewItem }; } - public static void GetContextMenuForBindingItem(InputActionsTreeViewItem targetElement) + public static void GetContextMenuForCompositeItem(InputActionsTreeViewItem treeViewItem, int index) { var _ = new ContextualMenuManipulator(menuEvent => { - AppendDeleteAction(menuEvent, targetElement); - }) { target = targetElement }; + AppendRenameAction(menuEvent, index, treeViewItem); + AppendDeleteAction(menuEvent, treeViewItem); + }) { target = treeViewItem }; + } + + public static void GetContextMenuForBindingItem(InputActionsTreeViewItem treeViewItem) + { + var _ = new ContextualMenuManipulator(menuEvent => + { + AppendDeleteAction(menuEvent, treeViewItem); + }) { target = treeViewItem }; + } + + private static void AppendDeleteAction(ContextualMenuPopulateEvent menuEvent, InputActionsTreeViewItem treeViewItem) + { + menuEvent.menu.AppendAction(delete_String, _ => {InputActionViewsControlsHolder.DeleteAction.Invoke(treeViewItem);}); } - private static void AppendDeleteAction(ContextualMenuPopulateEvent menuEvent, InputActionsTreeViewItem targetElement) + private static void AppendRenameAction(ContextualMenuPopulateEvent menuEvent, int index, InputActionsTreeViewItem treeViewItem) { - menuEvent.menu.AppendAction(delete_String, action => {targetElement.DeleteItem();}); + menuEvent.menu.AppendAction(rename_String, _ => {InputActionViewsControlsHolder.RenameAction.Invoke(index, treeViewItem);}); } } } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs new file mode 100644 index 0000000000..8fb525485e --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs @@ -0,0 +1,82 @@ +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +using System; +using UnityEngine.UIElements; + +namespace UnityEngine.InputSystem.Editor +{ + internal static class InputActionViewsControlsHolder + { + private static TreeView m_TreeView; + private static ActionsTreeView m_ActionsTreeView; + private static ListView m_ListView; + internal static Action RenameAction => RenameActionItem; + internal static Action RenameActionMap => RenameActionMapItem; + internal static Action DeleteAction => Delete; + internal static Action AddBinding => AddNewBinding; + internal static Action AddCompositePositivNegativModifier => AddNewPositiveNegativeComposite; + internal static Action AddCompositeOneModifier => AddNewOneModifierComposite; + internal static Action AddCompositeTwoModifier => AddNewTwoModifierComposite; + internal static Action CreateAction => CreateNewAction; + + internal static void Initialize(VisualElement root, ActionsTreeView actionsTreeView) + { + m_TreeView = root?.Q("actions-tree-view"); + m_ActionsTreeView = actionsTreeView; + m_ListView = root?.Q("action-maps-list-view"); + } + + private static void RenameActionItem(int index, InputActionsTreeViewItem treeViewItem) + { + m_TreeView.SetSelection(index); + treeViewItem.FocusOnRenameTextField(); + } + + private static void RenameActionMapItem(InputActionsTreeViewItem treeViewItem) + { + var index = m_ListView.itemsSource.IndexOf(treeViewItem.label.text); + if (index < 0 || index >= m_ListView.itemsSource.Count) + return; + m_ListView.SetSelection(index); + treeViewItem.FocusOnRenameTextField(); + } + + private static void Delete(InputActionsTreeViewItem treeViewItem) + { + treeViewItem.DeleteItem(); + } + + private static void CreateNewAction(InputActionsTreeViewItem item) + { + var index = m_ListView.itemsSource.IndexOf(item.label.text); + if (index < 0 || index >= m_ListView.itemsSource.Count) + return; + m_ListView.SetSelection(index); + m_ActionsTreeView.AddAction(); + } + + private static void AddNewBinding(InputActionsTreeViewItem inputActionsTreeViewItem) + { + var action = inputActionsTreeViewItem.label.text; + m_ActionsTreeView.AddBinding(action); + } + + private static void AddNewPositiveNegativeComposite(InputActionsTreeViewItem inputActionsTreeViewItem) + { + var action = inputActionsTreeViewItem.label.text; + m_ActionsTreeView.AddComposite(action, "1DAxis"); + } + + private static void AddNewOneModifierComposite(InputActionsTreeViewItem inputActionsTreeViewItem) + { + var action = inputActionsTreeViewItem.label.text; + m_ActionsTreeView.AddComposite(action, "OneModifier"); + } + + private static void AddNewTwoModifierComposite(InputActionsTreeViewItem inputActionsTreeViewItem) + { + var action = inputActionsTreeViewItem.label.text; + m_ActionsTreeView.AddComposite(action, "TwoModifiers"); + } + } +} +#endif diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs.meta new file mode 100644 index 0000000000..21dfaffe06 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 08ab31769bde64d3cb067b9b9d166e64 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs index 623e69dde7..ab046b4a20 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs @@ -28,9 +28,11 @@ public void BuildUI() InputActionsEditorConstants.MainEditorViewNameUxml); mainEditorAsset.CloneTree(m_Root); + var actionsTreeView = new ActionsTreeView(m_Root, stateContainer); CreateChildView(new ActionMapsView(m_Root, stateContainer)); - CreateChildView(new ActionsTreeView(m_Root, stateContainer)); + CreateChildView(actionsTreeView); CreateChildView(new PropertiesView(m_Root, stateContainer)); + InputActionViewsControlsHolder.Initialize(m_Root, actionsTreeView); var menuButton = m_Root.Q("control-schemes-toolbar-menu"); menuButton.menu.AppendAction("Add Control Scheme...", _ => AddOrUpdateControlScheme(m_Root)); diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/PropertiesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/PropertiesView.cs index 47dbd73ba3..2c1ed6d523 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/PropertiesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/PropertiesView.cs @@ -146,7 +146,7 @@ public override void RedrawUI(ViewState viewState) { case SelectionType.Action: m_Root.Q