Skip to content

Commit

Permalink
FIX: Allow Copy/Paste between windows by intercepting the commands hi…
Browse files Browse the repository at this point in the history
…gher up the hierarchy. (ISX-1823)
  • Loading branch information
graham-huws committed Feb 15, 2024
1 parent 6db0cc5 commit 8944d39
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
1 change: 1 addition & 0 deletions Packages/com.unity.inputsystem/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ however, it has to be formatted properly to pass verification tests.
- Fixed InputManager.asset file growing in size on each Reset call.
- Fixed Opening InputDebugger throws 'Action map must have state at this point' error
- Fixed Cut/Paste behaviour to match Editor - Cut items will now be cleared from clipboard after pasting.
- Fixed Pasting items between windows not working until an item in the Action Map/Action lists was selected.

## [1.8.0-pre.2] - 2023-11-09

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ private static void PasteActionsFromClipboard(InputActionsEditorState state, boo
var index = state.selectedActionIndex;
if (addLast)
index = actionArray.arraySize - 1;

if (index < 0)
index = 0;

PasteData(EditorGUIUtility.systemCopyBuffer, new[] {index}, actionArray);
}

Expand Down Expand Up @@ -288,13 +292,14 @@ private static void PasteAction(SerializedProperty arrayProperty, string jsonToI
private static int PasteBindingOrComposite(SerializedProperty arrayProperty, string json, int index, string actionName, bool createCompositeParts = true)
{
var pastePartOfComposite = IsPartOfComposite(json);
if (index > 0)
if (index > 0 && arrayProperty.arraySize > 0 && index - 1 < arrayProperty.arraySize)
{
var currentProperty = arrayProperty.GetArrayElementAtIndex(index - 1);
var currentIsComposite = IsComposite(currentProperty) || IsPartOfComposite(currentProperty);
if (pastePartOfComposite && !currentIsComposite) //prevent pasting part of composite into non-composite
return index;
}

index = pastePartOfComposite || s_State.selectionType == SelectionType.Action ? index : Selectors.GetSelectedBindingIndexAfterCompositeBindings(s_State) + 1;
if (json.Contains(k_BindingData)) //copied data is composite with bindings - only true for directly copied composites, not for composites from copied actions
return PasteCompositeFromJson(arrayProperty, json, index, actionName);
Expand Down Expand Up @@ -351,7 +356,7 @@ private static bool IsPartOfComposite(string json)
private static SerializedProperty AddElement(SerializedProperty arrayProperty, string name, int index = -1)
{
var uniqueName = InputActionSerializationHelpers.FindUniqueName(arrayProperty, name);
if (index < 0)
if (index < 0 || index > arrayProperty.arraySize)
index = arrayProperty.arraySize;

arrayProperty.InsertArrayElementAtIndex(index);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
using CmdEvents = UnityEngine.InputSystem.Editor.InputActionsEditorConstants.CommandEvents;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -14,6 +15,8 @@ internal class InputActionsEditorView : ViewBase<InputActionsEditorView.ViewStat
private const string autoSaveToggleId = "auto-save-toolbar-toggle";
private const string menuButtonId = "asset-menu";

private readonly TreeView m_ActionsTreeView;
private readonly ListView m_ActionMapsListView;
private readonly ToolbarMenu m_MenuButtonToolbar;
private readonly ToolbarButton m_SaveButton;

Expand Down Expand Up @@ -71,6 +74,13 @@ public InputActionsEditorView(VisualElement root, StateContainer stateContainer)
controlSchemes = controlSchemes,
selectedControlSchemeIndex = state.selectedControlSchemeIndex
});

m_ActionsTreeView = root.Q<TreeView>("actions-tree-view");
m_ActionMapsListView = root.Q<ListView>("action-maps-list-view");

root.RegisterCallback<ValidateCommandEvent>(OnValidateCommand);
root.RegisterCallback<ExecuteCommandEvent>(OnExecuteCommand);
root.focusable = true; // Required for CommandEvents to work
}

private void OnReset()
Expand Down Expand Up @@ -159,6 +169,49 @@ public class ViewState
public IEnumerable<InputControlScheme> controlSchemes;
public int selectedControlSchemeIndex;
}

void OnExecuteCommand(ExecuteCommandEvent evt)
{
if (evt.commandName != CmdEvents.Paste)
return;

var copiedType = CopyPasteHelper.GetCopiedClipboardType();

if (copiedType == typeof(InputActionMap))
{
Dispatch(Commands.PasteActionMaps());
}
else if (copiedType == typeof(InputAction))
{
// Can't paste an Action without any Action Maps for it to go to
if (m_ActionMapsListView.itemsSource.Count > 0)
Dispatch(Commands.PasteActionsOrBindings());
}
else if (copiedType == typeof(InputBinding))
{
// Can't paste a Binding without any Actions for it to go to
if (m_ActionsTreeView.itemsSource.Count > 0)
{
var oldSelectedBinding = stateContainer.GetState().selectedBindingIndex;
Dispatch(Commands.PasteActionsOrBindings());

// If paste succeeded, expand the relevant Action to show the new binding.
if (stateContainer.GetState().selectedBindingIndex != oldSelectedBinding)
m_ActionsTreeView.ExpandItem(m_ActionsTreeView.GetIdForIndex(stateContainer.GetState().selectedActionIndex));
}
}
}

void OnValidateCommand(ValidateCommandEvent evt)
{
// Mark commands as supported for Execute by stopping propagation of the event
switch (evt.commandName)
{
case CmdEvents.Paste:
evt.StopPropagation();
break;
}
}
}

internal static partial class Selectors
Expand Down

0 comments on commit 8944d39

Please sign in to comment.