Skip to content

Commit a0219d1

Browse files
authored
FIX: Fixed pasting bindings into empty Input Action asset (case ISXB-1180) - take #2 (#2049)
o Ensure PasteBlocks() deals with invalid selection - when copied type is binding we need to have a valid Action selected to paste into. o Ensure Paste option is only present in context menu when appropriate. o Fix menu separator presence (or absense). o Action Maps view: can Paste ActionMap or Action (if a map is present). o Actions view: can paste Actions or Bindings depending on selected item context.
1 parent 343e8bf commit a0219d1

File tree

2 files changed

+83
-18
lines changed

2 files changed

+83
-18
lines changed

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

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ internal static class ContextMenu
2525
private static readonly string add_Binding_String = "Add Binding";
2626

2727
#region ActionMaps
28+
// Determine whether current clipboard contents can can pasted into the ActionMaps view
29+
//
30+
// can always paste an ActionMap
31+
// need an existing map to be able to paste an Action
32+
//
33+
private static bool CanPasteIntoActionMaps(ActionMapsView mapView)
34+
{
35+
bool haveMap = mapView.GetMapCount() > 0;
36+
var copiedType = CopyPasteHelper.GetCopiedClipboardType();
37+
bool copyIsMap = copiedType == typeof(InputActionMap);
38+
bool copyIsAction = copiedType == typeof(InputAction);
39+
bool hasPastableData = (copyIsMap || (copyIsAction && haveMap));
40+
return hasPastableData;
41+
}
42+
2843
public static void GetContextMenuForActionMapItem(ActionMapsView mapView, InputActionMapsTreeViewItem treeViewItem, int index)
2944
{
3045
treeViewItem.OnContextualMenuPopulateEvent = (menuEvent =>
@@ -39,9 +54,15 @@ public static void GetContextMenuForActionMapItem(ActionMapsView mapView, InputA
3954
menuEvent.menu.AppendAction(copy_String, _ => mapView.CopyItems());
4055
menuEvent.menu.AppendAction(cut_String, _ => mapView.CutItems());
4156

42-
var copiedAction = CopyPasteHelper.GetCopiedClipboardType() == typeof(InputAction);
43-
if (CopyPasteHelper.HasPastableClipboardData(typeof(InputActionMap)))
44-
menuEvent.menu.AppendAction(paste_String, _ => mapView.PasteItems(copiedAction));
57+
if (CanPasteIntoActionMaps(mapView))
58+
{
59+
bool copyIsAction = CopyPasteHelper.GetCopiedClipboardType() == typeof(InputAction);
60+
if (CopyPasteHelper.HasPastableClipboardData(typeof(InputActionMap)))
61+
menuEvent.menu.AppendAction(paste_String, _ => mapView.PasteItems(copyIsAction));
62+
}
63+
64+
menuEvent.menu.AppendSeparator();
65+
menuEvent.menu.AppendAction(add_Action_Map_String, _ => mapView.AddActionMap());
4566
});
4667
}
4768

@@ -51,27 +72,60 @@ public static void GetContextMenuForActionMapsEmptySpace(ActionMapsView mapView,
5172
{
5273
_ = new ContextualMenuManipulator(menuEvent =>
5374
{
54-
var copiedAction = CopyPasteHelper.GetCopiedClipboardType() == typeof(InputAction);
55-
if (CopyPasteHelper.HasPastableClipboardData(typeof(InputActionMap)))
56-
menuEvent.menu.AppendAction(paste_String, _ => mapView.PasteItems(copiedAction));
57-
58-
menuEvent.menu.AppendSeparator();
75+
if (CanPasteIntoActionMaps(mapView))
76+
{
77+
bool copyIsAction = CopyPasteHelper.GetCopiedClipboardType() == typeof(InputAction);
78+
menuEvent.menu.AppendAction(paste_String, _ => mapView.PasteItems(copyIsAction));
79+
menuEvent.menu.AppendSeparator();
80+
}
5981
menuEvent.menu.AppendAction(add_Action_Map_String, _ => mapView.AddActionMap());
6082
}) { target = element };
6183
}
6284

6385
#endregion
6486

6587
#region Actions
88+
// Determine whether current clipboard contents can pasted into the Actions TreeView
89+
//
90+
// item selected => can paste either Action or Binding (depends on selected item context)
91+
// empty view => can only paste Action
92+
// no selection => can only paste Action
93+
//
94+
private static bool CanPasteIntoActions(TreeView treeView)
95+
{
96+
bool hasPastableData = false;
97+
bool selected = treeView.selectedIndex != -1;
98+
if (selected)
99+
{
100+
var item = treeView.GetItemDataForIndex<ActionOrBindingData>(treeView.selectedIndex);
101+
var itemType = item.isAction ? typeof(InputAction) : typeof(InputBinding);
102+
hasPastableData = CopyPasteHelper.HasPastableClipboardData(itemType);
103+
}
104+
else
105+
{
106+
// Cannot paste Binding when no Action is selected or into an empty view
107+
bool copyIsBinding = CopyPasteHelper.GetCopiedClipboardType() == typeof(InputBinding);
108+
hasPastableData = !copyIsBinding && CopyPasteHelper.HasPastableClipboardData(typeof(InputAction));
109+
}
110+
return hasPastableData;
111+
}
112+
66113
// Add the "Paste" option to all elements in the Action area.
67114
public static void GetContextMenuForActionListView(ActionsTreeView actionsTreeView, TreeView treeView, VisualElement target)
68115
{
69116
_ = new ContextualMenuManipulator(menuEvent =>
70117
{
71-
var item = treeView.GetItemDataForIndex<ActionOrBindingData>(treeView.selectedIndex);
72-
var hasPastableData = CopyPasteHelper.HasPastableClipboardData(item.isAction ? typeof(InputAction) : typeof(InputBinding));
73-
if (hasPastableData)
74-
menuEvent.menu.AppendAction(paste_String, _ => actionsTreeView.PasteItems());
118+
bool haveMap = actionsTreeView.GetMapCount() > 0;
119+
if (haveMap)
120+
{
121+
bool hasPastableData = CanPasteIntoActions(treeView);
122+
if (hasPastableData)
123+
{
124+
menuEvent.menu.AppendAction(paste_String, _ => actionsTreeView.PasteItems());
125+
}
126+
menuEvent.menu.AppendSeparator();
127+
menuEvent.menu.AppendAction(add_Action_String, _ => actionsTreeView.AddAction());
128+
}
75129
}) { target = target };
76130
}
77131

@@ -81,13 +135,15 @@ public static void GetContextMenuForActionsEmptySpace(ActionsTreeView actionsTre
81135
{
82136
_ = new ContextualMenuManipulator(menuEvent =>
83137
{
84-
if (actionsTreeView.GetMapCount() > 0 && (!onlyShowIfTreeIsEmpty || treeView.GetTreeCount() == 0))
138+
bool haveMap = actionsTreeView.GetMapCount() > 0;
139+
if (haveMap && (!onlyShowIfTreeIsEmpty || treeView.GetTreeCount() == 0))
85140
{
86-
var item = treeView.GetItemDataForIndex<ActionOrBindingData>(treeView.selectedIndex);
87-
if (CopyPasteHelper.HasPastableClipboardData(item.isAction ? typeof(InputAction) : typeof(InputBinding)))
141+
bool hasPastableData = CanPasteIntoActions(treeView);
142+
if (hasPastableData)
143+
{
88144
menuEvent.menu.AppendAction(paste_String, _ => actionsTreeView.PasteItems());
89-
90-
menuEvent.menu.AppendSeparator();
145+
menuEvent.menu.AppendSeparator();
146+
}
91147
menuEvent.menu.AppendAction(add_Action_String, _ => actionsTreeView.AddAction());
92148
}
93149
}) { target = target };

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,17 @@ private static void PasteBlocks(string transmission, int indexToInsert, Serializ
266266
{
267267
var actionName = Selectors.GetSelectedBinding(s_State)?.wrappedProperty.FindPropertyRelative("m_Action")
268268
.stringValue;
269+
269270
if (s_State.selectionType == SelectionType.Action)
270-
actionName = PropertyName(Selectors.GetSelectedAction(s_State)?.wrappedProperty);
271+
{
272+
SerializedProperty property = Selectors.GetSelectedAction(s_State)?.wrappedProperty;
273+
if (property == null)
274+
return;
275+
actionName = PropertyName(property);
276+
}
277+
if (actionName == null)
278+
return;
279+
271280
PasteBindingOrComposite(arrayToInsertInto, block, indexToInsert, actionName);
272281
}
273282
}

0 commit comments

Comments
 (0)