Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -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<BlurEvent>(_ => OnEditEnd());
field.RegisterValueChangedCallback(_ => OnEditEnd());
root.Add(field);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ namespace UnityEngine.InputSystem.Editor
internal class ActionPropertiesView : ViewBase<(SerializedInputAction?, List<string>)>
{
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<T> and how to compare selector data
CreateSelector(Selectors.GetSelectedAction,
Expand All @@ -31,6 +33,8 @@ public override void RedrawUI((SerializedInputAction ? , List<string>) viewState
{
if (!viewState.Item1.HasValue)
return;

m_ParentFoldout.text = "Action";
var inputAction = viewState.Item1.Value;

m_Root.Clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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<InputActionsTreeViewItem>();
treeViewItem.FocusOnRenameTextField();
var treeViewItem = m_ActionsTreeView.GetRootElementForId(id)?.Q<InputActionsTreeViewItem>();
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)
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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()); });

Expand Down
Original file line number Diff line number Diff line change
@@ -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);});
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<int, InputActionsTreeViewItem> RenameAction => RenameActionItem;
internal static Action<InputActionsTreeViewItem> RenameActionMap => RenameActionMapItem;
internal static Action<InputActionsTreeViewItem> DeleteAction => Delete;
internal static Action<InputActionsTreeViewItem> AddBinding => AddNewBinding;
internal static Action<InputActionsTreeViewItem> AddCompositePositivNegativModifier => AddNewPositiveNegativeComposite;
internal static Action<InputActionsTreeViewItem> AddCompositeOneModifier => AddNewOneModifierComposite;
internal static Action<InputActionsTreeViewItem> AddCompositeTwoModifier => AddNewTwoModifierComposite;
internal static Action<InputActionsTreeViewItem> CreateAction => CreateNewAction;

internal static void Initialize(VisualElement root, ActionsTreeView actionsTreeView)
{
m_TreeView = root?.Q<TreeView>("actions-tree-view");
m_ActionsTreeView = actionsTreeView;
m_ListView = root?.Q<ListView>("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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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<ToolbarMenu>("control-schemes-toolbar-menu");
menuButton.menu.AppendAction("Add Control Scheme...", _ => AddOrUpdateControlScheme(m_Root));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public override void RedrawUI(ViewState viewState)
{
case SelectionType.Action:
m_Root.Q<Label>("properties-header-label").text = "Action Properties";
m_ActionPropertyView = CreateChildView(new ActionPropertiesView(visualElement, stateContainer));
m_ActionPropertyView = CreateChildView(new ActionPropertiesView(visualElement, foldout, stateContainer));
break;

case SelectionType.Binding:
Expand Down