Skip to content

Commit 94d27e7

Browse files
committed
FIX: Allow Copy/Paste between windows by intercepting the commands higher up the hierarchy. (ISX-1823)
1 parent 6db0cc5 commit 94d27e7

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ private static void PasteActionsFromClipboard(InputActionsEditorState state, boo
204204
var index = state.selectedActionIndex;
205205
if (addLast)
206206
index = actionArray.arraySize - 1;
207+
208+
if (index < 0)
209+
index = 0;
210+
207211
PasteData(EditorGUIUtility.systemCopyBuffer, new[] {index}, actionArray);
208212
}
209213

@@ -288,13 +292,14 @@ private static void PasteAction(SerializedProperty arrayProperty, string jsonToI
288292
private static int PasteBindingOrComposite(SerializedProperty arrayProperty, string json, int index, string actionName, bool createCompositeParts = true)
289293
{
290294
var pastePartOfComposite = IsPartOfComposite(json);
291-
if (index > 0)
295+
if (index > 0 && arrayProperty.arraySize > 0 && index - 1 < arrayProperty.arraySize)
292296
{
293297
var currentProperty = arrayProperty.GetArrayElementAtIndex(index - 1);
294298
var currentIsComposite = IsComposite(currentProperty) || IsPartOfComposite(currentProperty);
295299
if (pastePartOfComposite && !currentIsComposite) //prevent pasting part of composite into non-composite
296300
return index;
297301
}
302+
298303
index = pastePartOfComposite || s_State.selectionType == SelectionType.Action ? index : Selectors.GetSelectedBindingIndexAfterCompositeBindings(s_State) + 1;
299304
if (json.Contains(k_BindingData)) //copied data is composite with bindings - only true for directly copied composites, not for composites from copied actions
300305
return PasteCompositeFromJson(arrayProperty, json, index, actionName);
@@ -351,7 +356,7 @@ private static bool IsPartOfComposite(string json)
351356
private static SerializedProperty AddElement(SerializedProperty arrayProperty, string name, int index = -1)
352357
{
353358
var uniqueName = InputActionSerializationHelpers.FindUniqueName(arrayProperty, name);
354-
if (index < 0)
359+
if (index < 0 || index > arrayProperty.arraySize)
355360
index = arrayProperty.arraySize;
356361

357362
arrayProperty.InsertArrayElementAtIndex(index);

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

+53
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
2+
using CmdEvents = UnityEngine.InputSystem.Editor.InputActionsEditorConstants.CommandEvents;
23
using System;
34
using System.Collections.Generic;
45
using System.Linq;
@@ -14,6 +15,8 @@ internal class InputActionsEditorView : ViewBase<InputActionsEditorView.ViewStat
1415
private const string autoSaveToggleId = "auto-save-toolbar-toggle";
1516
private const string menuButtonId = "asset-menu";
1617

18+
private readonly TreeView m_ActionsTreeView;
19+
private readonly ListView m_ActionMapsListView;
1720
private readonly ToolbarMenu m_MenuButtonToolbar;
1821
private readonly ToolbarButton m_SaveButton;
1922

@@ -71,6 +74,13 @@ public InputActionsEditorView(VisualElement root, StateContainer stateContainer)
7174
controlSchemes = controlSchemes,
7275
selectedControlSchemeIndex = state.selectedControlSchemeIndex
7376
});
77+
78+
m_ActionsTreeView = root.Q<TreeView>("actions-tree-view");
79+
m_ActionMapsListView = root.Q<ListView>("action-maps-list-view");
80+
81+
root.RegisterCallback<ValidateCommandEvent>(OnValidateCommand);
82+
root.RegisterCallback<ExecuteCommandEvent>(OnExecuteCommand);
83+
root.focusable = true; // Required for CommandEvents to work
7484
}
7585

7686
private void OnReset()
@@ -159,6 +169,49 @@ public class ViewState
159169
public IEnumerable<InputControlScheme> controlSchemes;
160170
public int selectedControlSchemeIndex;
161171
}
172+
173+
void OnExecuteCommand(ExecuteCommandEvent evt)
174+
{
175+
if (evt.commandName != CmdEvents.Paste)
176+
return;
177+
178+
var copiedType = CopyPasteHelper.GetCopiedClipboardType();
179+
180+
if (copiedType == typeof(InputActionMap))
181+
{
182+
Dispatch(Commands.PasteActionMaps());
183+
}
184+
else if (copiedType == typeof(InputAction))
185+
{
186+
// Can't paste an Action without any Action Maps for it to go to
187+
if (m_ActionMapsListView.itemsSource.Count > 0)
188+
Dispatch(Commands.PasteActionsOrBindings());
189+
}
190+
else if (copiedType == typeof(InputBinding))
191+
{
192+
// Can't paste a Binding without any Actions for it to go to
193+
if (m_ActionsTreeView.itemsSource.Count > 0)
194+
{
195+
var oldSelectedBinding = stateContainer.GetState().selectedBindingIndex;
196+
Dispatch(Commands.PasteActionsOrBindings());
197+
198+
// If paste succeeded, expand the relevant Action to show the new binding.
199+
if (stateContainer.GetState().selectedBindingIndex != oldSelectedBinding)
200+
m_ActionsTreeView.ExpandItem(m_ActionsTreeView.GetIdForIndex(stateContainer.GetState().selectedActionIndex));
201+
}
202+
}
203+
}
204+
205+
void OnValidateCommand(ValidateCommandEvent evt)
206+
{
207+
// Mark commands as supported for Execute by stopping propagation of the event
208+
switch (evt.commandName)
209+
{
210+
case CmdEvents.Paste:
211+
evt.StopPropagation();
212+
break;
213+
}
214+
}
162215
}
163216

164217
internal static partial class Selectors

0 commit comments

Comments
 (0)