Skip to content

Commit 1faaaa5

Browse files
authored
NEW: add composites and right click support (ISX-1372) (#1711)
* WIP added controls holder for context menu & more context menu options * null reference fix for adding actions on actionmaps * added functions for adding different types of composites * fixed names for bindings in composites * fixed text or properties foldout * fix for saving bool toggle values * fixed wrong action map focused on right click bug * fix formatting * fix formatting This reverts commit 1860c26.
1 parent 6617fd6 commit 1faaaa5

11 files changed

Lines changed: 176 additions & 41 deletions

File tree

Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ void OnEditEnd()
321321
var boolValue = parameter.value.value.ToBoolean();
322322
var field = new Toggle(label.text) { value = boolValue };
323323
field.RegisterValueChangedCallback(evt => OnValueChanged(ref parameter, evt.newValue, closedIndex));
324-
field.RegisterCallback<BlurEvent>(_ => OnEditEnd());
324+
field.RegisterValueChangedCallback(_ => OnEditEnd());
325325
root.Add(field);
326326
}
327327
}

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ public static Command AddBinding()
6969
};
7070
}
7171

72+
public static Command AddComposite(string compositeName)
73+
{
74+
return (in InputActionsEditorState state) =>
75+
{
76+
var action = Selectors.GetSelectedAction(state)?.wrappedProperty;
77+
var map = Selectors.GetSelectedActionMap(state)?.wrappedProperty;
78+
var compositeType = InputBindingComposite.s_Composites.LookupTypeRegistration(compositeName);
79+
var composite = InputActionSerializationHelpers.AddCompositeBinding(action, map, compositeName, compositeType);
80+
var index = new SerializedInputBinding(composite).indexOfBinding;
81+
state.serializedObject.ApplyModifiedProperties();
82+
return state.With(selectedBindingIndex: index, selectionType: SelectionType.Binding);
83+
};
84+
}
85+
7286
public static Command DeleteActionMap(int actionMapIndex)
7387
{
7488
return (in InputActionsEditorState state) =>

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public ActionMapsView(VisualElement root, StateContainer stateContainer)
2929
treeViewItem.DeleteCallback = _ => DeleteActionMap(i);
3030
treeViewItem.OnDeleteItem += treeViewItem.DeleteCallback;
3131

32-
ContextMenu.GetContextMenuForActionMapItem(treeViewItem, m_ListView);
32+
ContextMenu.GetContextMenuForActionMapItem(treeViewItem);
3333
};
3434
m_ListView.makeItem = () => new InputActionsTreeViewItem();
3535
m_ListView.unbindItem = (element, i) =>

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ namespace UnityEngine.InputSystem.Editor
1111
internal class ActionPropertiesView : ViewBase<(SerializedInputAction?, List<string>)>
1212
{
1313
private readonly VisualElement m_Root;
14+
private readonly Foldout m_ParentFoldout;
1415

15-
public ActionPropertiesView(VisualElement root, StateContainer stateContainer)
16+
public ActionPropertiesView(VisualElement root, Foldout foldout, StateContainer stateContainer)
1617
: base(stateContainer)
1718
{
1819
m_Root = root;
20+
m_ParentFoldout = foldout;
1921

2022
// TODO: Consider IEquatable<T> and how to compare selector data
2123
CreateSelector(Selectors.GetSelectedAction,
@@ -31,6 +33,8 @@ public override void RedrawUI((SerializedInputAction ? , List<string>) viewState
3133
{
3234
if (!viewState.Item1.HasValue)
3335
return;
36+
37+
m_ParentFoldout.text = "Action";
3438
var inputAction = viewState.Item1.Value;
3539

3640
m_Root.Clear();

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ public ActionsTreeView(VisualElement root, StateContainer stateContainer)
3737
var treeViewItem = (InputActionsTreeViewItem)e;
3838
treeViewItem.DeleteCallback = _ => DeleteItem(item);
3939
treeViewItem.OnDeleteItem += treeViewItem.DeleteCallback;
40-
41-
if (item.isAction || item.isComposite)
42-
ContextMenu.GetContextMenuForActionOrCompositeItem(treeViewItem, m_ActionsTreeView, i);
40+
if (item.isComposite)
41+
ContextMenu.GetContextMenuForCompositeItem(treeViewItem, i);
42+
else if (item.isAction)
43+
ContextMenu.GetContextMenuForActionItem(treeViewItem, i);
4344
else
4445
ContextMenu.GetContextMenuForBindingItem(treeViewItem);
4546

@@ -183,22 +184,28 @@ private void RenameNewAction(int id)
183184
if (!m_RenameOnActionAdded || id == -1)
184185
return;
185186
m_ActionsTreeView.ScrollToItemById(id);
186-
var treeViewItem = m_ActionsTreeView.GetRootElementForId(id).Q<InputActionsTreeViewItem>();
187-
treeViewItem.FocusOnRenameTextField();
187+
var treeViewItem = m_ActionsTreeView.GetRootElementForId(id)?.Q<InputActionsTreeViewItem>();
188+
treeViewItem?.FocusOnRenameTextField();
188189
}
189190

190-
private void AddAction()
191+
internal void AddAction()
191192
{
192193
Dispatch(Commands.AddAction());
193194
m_RenameOnActionAdded = true;
194195
}
195196

196-
private void AddBinding(string actionName)
197+
internal void AddBinding(string actionName)
197198
{
198199
Dispatch(Commands.SelectAction(actionName));
199200
Dispatch(Commands.AddBinding());
200201
}
201202

203+
internal void AddComposite(string actionName, string compositeType)
204+
{
205+
Dispatch(Commands.SelectAction(actionName));
206+
Dispatch(Commands.AddComposite(compositeType));
207+
}
208+
202209
private void DeleteItem(ActionOrBindingData data)
203210
{
204211
if (data.isAction)
@@ -347,7 +354,7 @@ private static string GetHumanReadableBindingName(SerializedInputBinding seriali
347354
internal static string GetHumanReadableCompositeName(SerializedInputBinding binding)
348355
{
349356
return $"{ObjectNames.NicifyVariableName(binding.name)}: " +
350-
$"{InputControlPath.ToHumanReadableString(binding.path)}";
357+
$"{GetHumanReadableBindingName(binding)}";
351358
}
352359

353360
private static string GetControlLayout(string path)

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public override void RedrawUI(ViewState viewState)
4141
var binding = viewState.selectedBinding;
4242
if (!binding.HasValue)
4343
return;
44+
45+
m_ParentFoldout.text = "Binding";
4446
if (binding.Value.isComposite)
4547
{
4648
m_ParentFoldout.text = "Composite";
@@ -53,8 +55,6 @@ public override void RedrawUI(ViewState viewState)
5355
}
5456
else
5557
{
56-
m_ParentFoldout.text = "Binding";
57-
5858
var controlPathEditor = new InputControlPathEditor(viewState.selectedBindingPath, new InputControlPickerState(),
5959
() => { Dispatch(Commands.ApplyModifiedProperties()); });
6060

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,68 @@
11
#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR
2-
using System;
3-
using System.Collections.Generic;
4-
using System.Linq;
5-
using UnityEditor;
62
using UnityEngine.UIElements;
73

84
namespace UnityEngine.InputSystem.Editor
95
{
10-
internal static partial class ContextMenu
6+
internal static class ContextMenu
117
{
128
private static readonly string rename_String = "Rename";
139
private static readonly string delete_String = "Delete";
14-
public static void GetContextMenuForActionMapItem(InputActionsTreeViewItem targetElement, ListView listView)
10+
11+
private static readonly string add_Action_String = "Add Action";
12+
private static readonly string add_Binding_String = "Add Binding";
13+
private static readonly string add_positiveNegative_Binding_String = "Add Positive\\Negative Binding";
14+
private static readonly string add_oneModifier_Binding_String = "Add Binding With One Modifier";
15+
private static readonly string add_twoModifier_Binding_String = "Add Binding With Two Modifiers";
16+
public static void GetContextMenuForActionMapItem(InputActionsTreeViewItem treeViewItem)
1517
{
1618
var _ = new ContextualMenuManipulator(menuEvent =>
1719
{
18-
menuEvent.menu.AppendAction(rename_String, action =>
19-
{
20-
listView.SetSelection(listView.itemsSource.IndexOf(targetElement.label.text));
21-
targetElement.FocusOnRenameTextField();
22-
});
23-
AppendDeleteAction(menuEvent, targetElement);
24-
}) { target = targetElement };
20+
menuEvent.menu.AppendAction(add_Action_String, _ => InputActionViewsControlsHolder.CreateAction.Invoke(treeViewItem));
21+
menuEvent.menu.AppendSeparator();
22+
menuEvent.menu.AppendAction(rename_String, _ => InputActionViewsControlsHolder.RenameActionMap.Invoke(treeViewItem));
23+
AppendDeleteAction(menuEvent, treeViewItem);
24+
}) { target = treeViewItem };
2525
}
2626

27-
public static void GetContextMenuForActionOrCompositeItem(InputActionsTreeViewItem targetElement, TreeView treeView, int index)
27+
public static void GetContextMenuForActionItem(InputActionsTreeViewItem treeViewItem, int index)
2828
{
2929
var _ = new ContextualMenuManipulator(menuEvent =>
3030
{
31-
menuEvent.menu.AppendAction(rename_String, action =>
32-
{
33-
treeView.SetSelection(index);
34-
targetElement.FocusOnRenameTextField();
35-
});
36-
AppendDeleteAction(menuEvent, targetElement);
37-
}) { target = targetElement };
31+
menuEvent.menu.AppendAction(add_Binding_String, _ => InputActionViewsControlsHolder.AddBinding.Invoke(treeViewItem));
32+
menuEvent.menu.AppendAction(add_positiveNegative_Binding_String, _ => InputActionViewsControlsHolder.AddCompositePositivNegativModifier.Invoke(treeViewItem));
33+
menuEvent.menu.AppendAction(add_oneModifier_Binding_String, _ => InputActionViewsControlsHolder.AddCompositeOneModifier.Invoke(treeViewItem));
34+
menuEvent.menu.AppendAction(add_twoModifier_Binding_String, _ => InputActionViewsControlsHolder.AddCompositeTwoModifier.Invoke(treeViewItem));
35+
menuEvent.menu.AppendSeparator();
36+
AppendRenameAction(menuEvent, index, treeViewItem);
37+
AppendDeleteAction(menuEvent, treeViewItem);
38+
}) { target = treeViewItem };
3839
}
3940

40-
public static void GetContextMenuForBindingItem(InputActionsTreeViewItem targetElement)
41+
public static void GetContextMenuForCompositeItem(InputActionsTreeViewItem treeViewItem, int index)
4142
{
4243
var _ = new ContextualMenuManipulator(menuEvent =>
4344
{
44-
AppendDeleteAction(menuEvent, targetElement);
45-
}) { target = targetElement };
45+
AppendRenameAction(menuEvent, index, treeViewItem);
46+
AppendDeleteAction(menuEvent, treeViewItem);
47+
}) { target = treeViewItem };
48+
}
49+
50+
public static void GetContextMenuForBindingItem(InputActionsTreeViewItem treeViewItem)
51+
{
52+
var _ = new ContextualMenuManipulator(menuEvent =>
53+
{
54+
AppendDeleteAction(menuEvent, treeViewItem);
55+
}) { target = treeViewItem };
56+
}
57+
58+
private static void AppendDeleteAction(ContextualMenuPopulateEvent menuEvent, InputActionsTreeViewItem treeViewItem)
59+
{
60+
menuEvent.menu.AppendAction(delete_String, _ => {InputActionViewsControlsHolder.DeleteAction.Invoke(treeViewItem);});
4661
}
4762

48-
private static void AppendDeleteAction(ContextualMenuPopulateEvent menuEvent, InputActionsTreeViewItem targetElement)
63+
private static void AppendRenameAction(ContextualMenuPopulateEvent menuEvent, int index, InputActionsTreeViewItem treeViewItem)
4964
{
50-
menuEvent.menu.AppendAction(delete_String, action => {targetElement.DeleteItem();});
65+
menuEvent.menu.AppendAction(rename_String, _ => {InputActionViewsControlsHolder.RenameAction.Invoke(index, treeViewItem);});
5166
}
5267
}
5368
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR
2+
using System;
3+
using UnityEngine.UIElements;
4+
5+
namespace UnityEngine.InputSystem.Editor
6+
{
7+
internal static class InputActionViewsControlsHolder
8+
{
9+
private static TreeView m_TreeView;
10+
private static ActionsTreeView m_ActionsTreeView;
11+
private static ListView m_ListView;
12+
internal static Action<int, InputActionsTreeViewItem> RenameAction => RenameActionItem;
13+
internal static Action<InputActionsTreeViewItem> RenameActionMap => RenameActionMapItem;
14+
internal static Action<InputActionsTreeViewItem> DeleteAction => Delete;
15+
internal static Action<InputActionsTreeViewItem> AddBinding => AddNewBinding;
16+
internal static Action<InputActionsTreeViewItem> AddCompositePositivNegativModifier => AddNewPositiveNegativeComposite;
17+
internal static Action<InputActionsTreeViewItem> AddCompositeOneModifier => AddNewOneModifierComposite;
18+
internal static Action<InputActionsTreeViewItem> AddCompositeTwoModifier => AddNewTwoModifierComposite;
19+
internal static Action<InputActionsTreeViewItem> CreateAction => CreateNewAction;
20+
21+
internal static void Initialize(VisualElement root, ActionsTreeView actionsTreeView)
22+
{
23+
m_TreeView = root?.Q<TreeView>("actions-tree-view");
24+
m_ActionsTreeView = actionsTreeView;
25+
m_ListView = root?.Q<ListView>("action-maps-list-view");
26+
}
27+
28+
private static void RenameActionItem(int index, InputActionsTreeViewItem treeViewItem)
29+
{
30+
m_TreeView.SetSelection(index);
31+
treeViewItem.FocusOnRenameTextField();
32+
}
33+
34+
private static void RenameActionMapItem(InputActionsTreeViewItem treeViewItem)
35+
{
36+
var index = m_ListView.itemsSource.IndexOf(treeViewItem.label.text);
37+
if (index < 0 || index >= m_ListView.itemsSource.Count)
38+
return;
39+
m_ListView.SetSelection(index);
40+
treeViewItem.FocusOnRenameTextField();
41+
}
42+
43+
private static void Delete(InputActionsTreeViewItem treeViewItem)
44+
{
45+
treeViewItem.DeleteItem();
46+
}
47+
48+
private static void CreateNewAction(InputActionsTreeViewItem item)
49+
{
50+
var index = m_ListView.itemsSource.IndexOf(item.label.text);
51+
if (index < 0 || index >= m_ListView.itemsSource.Count)
52+
return;
53+
m_ListView.SetSelection(index);
54+
m_ActionsTreeView.AddAction();
55+
}
56+
57+
private static void AddNewBinding(InputActionsTreeViewItem inputActionsTreeViewItem)
58+
{
59+
var action = inputActionsTreeViewItem.label.text;
60+
m_ActionsTreeView.AddBinding(action);
61+
}
62+
63+
private static void AddNewPositiveNegativeComposite(InputActionsTreeViewItem inputActionsTreeViewItem)
64+
{
65+
var action = inputActionsTreeViewItem.label.text;
66+
m_ActionsTreeView.AddComposite(action, "1DAxis");
67+
}
68+
69+
private static void AddNewOneModifierComposite(InputActionsTreeViewItem inputActionsTreeViewItem)
70+
{
71+
var action = inputActionsTreeViewItem.label.text;
72+
m_ActionsTreeView.AddComposite(action, "OneModifier");
73+
}
74+
75+
private static void AddNewTwoModifierComposite(InputActionsTreeViewItem inputActionsTreeViewItem)
76+
{
77+
var action = inputActionsTreeViewItem.label.text;
78+
m_ActionsTreeView.AddComposite(action, "TwoModifiers");
79+
}
80+
}
81+
}
82+
#endif

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ public void BuildUI()
2828
InputActionsEditorConstants.MainEditorViewNameUxml);
2929

3030
mainEditorAsset.CloneTree(m_Root);
31+
var actionsTreeView = new ActionsTreeView(m_Root, stateContainer);
3132
CreateChildView(new ActionMapsView(m_Root, stateContainer));
32-
CreateChildView(new ActionsTreeView(m_Root, stateContainer));
33+
CreateChildView(actionsTreeView);
3334
CreateChildView(new PropertiesView(m_Root, stateContainer));
35+
InputActionViewsControlsHolder.Initialize(m_Root, actionsTreeView);
3436

3537
var menuButton = m_Root.Q<ToolbarMenu>("control-schemes-toolbar-menu");
3638
menuButton.menu.AppendAction("Add Control Scheme...", _ => AddOrUpdateControlScheme(m_Root));

0 commit comments

Comments
 (0)