Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: collapsed and expanded treeview state is preserved when saving #2096

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using UnityEditor;

Expand Down Expand Up @@ -92,7 +91,6 @@ public InputActionsEditorState(
int selectedActionIndex = 0,
int selectedBindingIndex = 0,
SelectionType selectionType = SelectionType.Action,
Dictionary<(string, string), HashSet<int>> expandedBindingIndices = null,
InputControlScheme selectedControlScheme = default,
int selectedControlSchemeIndex = -1,
int selectedDeviceRequirementIndex = -1,
Expand All @@ -112,9 +110,6 @@ public InputActionsEditorState(
m_selectedControlSchemeIndex = selectedControlSchemeIndex;
m_selectedDeviceRequirementIndex = selectedDeviceRequirementIndex;

m_ExpandedCompositeBindings = expandedBindingIndices == null ?
new Dictionary<(string, string), HashSet<int>>() :
new Dictionary<(string, string), HashSet<int>>(expandedBindingIndices);
m_CutElements = cutElements;
}

Expand Down Expand Up @@ -201,12 +196,6 @@ public InputActionsEditorState(InputActionsEditorState other, SerializedObject a
m_ControlScheme = new InputControlScheme();
}

// Editor may leave these as null after domain reloads, so recreate them in that case.
// If they exist, we attempt to just preserve the same expanded items based on name for now for simplicity.
m_ExpandedCompositeBindings = other.m_ExpandedCompositeBindings == null ?
new Dictionary<(string, string), HashSet<int>>() :
new Dictionary<(string, string), HashSet<int>>(other.m_ExpandedCompositeBindings);

m_CutElements = other.cutElements;
}

Expand All @@ -218,7 +207,6 @@ public InputActionsEditorState With(
InputControlScheme? selectedControlScheme = null,
int? selectedControlSchemeIndex = null,
int? selectedDeviceRequirementIndex = null,
Dictionary<(string, string), HashSet<int>> expandedBindingIndices = null,
List<CutElement> cutElements = null)
{
return new InputActionsEditorState(
Expand All @@ -228,7 +216,6 @@ public InputActionsEditorState With(
selectedActionIndex ?? this.selectedActionIndex,
selectedBindingIndex ?? this.selectedBindingIndex,
selectionType ?? this.selectionType,
expandedBindingIndices ?? m_ExpandedCompositeBindings,

// Control schemes
selectedControlScheme ?? this.selectedControlScheme,
Expand All @@ -248,7 +235,6 @@ public InputActionsEditorState ClearCutElements()
selectedActionIndex,
selectedBindingIndex,
selectionType,
m_ExpandedCompositeBindings,
selectedControlScheme,
selectedControlSchemeIndex,
selectedDeviceRequirementIndex,
Expand All @@ -262,39 +248,6 @@ public SerializedProperty GetActionMapByName(string actionMapName)
.FirstOrDefault(p => p.FindPropertyRelative(nameof(InputActionMap.m_Name)).stringValue == actionMapName);
}

public InputActionsEditorState ExpandCompositeBinding(SerializedInputBinding binding)
{
var key = GetSelectedActionMapAndActionKey();

var expandedCompositeBindings = new Dictionary<(string, string), HashSet<int>>(m_ExpandedCompositeBindings);
if (!expandedCompositeBindings.TryGetValue(key, out var expandedStates))
{
expandedStates = new HashSet<int>();
expandedCompositeBindings.Add(key, expandedStates);
}

expandedStates.Add(binding.indexOfBinding);

return With(expandedBindingIndices: expandedCompositeBindings);
}

public InputActionsEditorState CollapseCompositeBinding(SerializedInputBinding binding)
{
var key = GetSelectedActionMapAndActionKey();

if (m_ExpandedCompositeBindings.ContainsKey(key) == false)
throw new InvalidOperationException("Trying to collapse a composite binding tree that was never expanded.");

// do the dance of C# immutability
var oldExpandedCompositeBindings = m_ExpandedCompositeBindings;
var expandedCompositeBindings = oldExpandedCompositeBindings.Keys.Where(dictKey => dictKey != key)
.ToDictionary(dictKey => dictKey, dictKey => oldExpandedCompositeBindings[dictKey]);
var newHashset = new HashSet<int>(m_ExpandedCompositeBindings[key].Where(index => index != binding.indexOfBinding));
expandedCompositeBindings.Add(key, newHashset);

return With(expandedBindingIndices: expandedCompositeBindings);
}

public InputActionsEditorState SelectAction(string actionName)
{
var actionMap = GetSelectedActionMap();
Expand Down Expand Up @@ -419,48 +372,11 @@ public readonly List<CutElement> GetCutElements()
return m_CutElements;
}

public ReadOnlyCollection<int> GetOrCreateExpandedState()
{
return new ReadOnlyCollection<int>(GetOrCreateExpandedStateInternal().ToList());
}

private HashSet<int> GetOrCreateExpandedStateInternal()
{
var key = GetSelectedActionMapAndActionKey();

if (m_ExpandedCompositeBindings.TryGetValue(key, out var expandedStates))
return expandedStates;

expandedStates = new HashSet<int>();
m_ExpandedCompositeBindings.Add(key, expandedStates);
return expandedStates;
}

internal (string, string) GetSelectedActionMapAndActionKey()
{
var selectedActionMap = GetSelectedActionMap();

var selectedAction = selectedActionMap
.FindPropertyRelative(nameof(InputActionMap.m_Actions))
.GetArrayElementAtIndex(selectedActionIndex);

var key = (
selectedActionMap.FindPropertyRelative(nameof(InputActionMap.m_Name)).stringValue,
selectedAction.FindPropertyRelative(nameof(InputAction.m_Name)).stringValue
);
return key;
}

private SerializedProperty GetSelectedActionMap()
{
return Selectors.GetActionMapAtIndex(serializedObject, selectedActionMapIndex)?.wrappedProperty;
}

/// <summary>
/// Expanded states for the actions tree view. These are stored per InputActionMap
/// </summary>
private readonly Dictionary<(string, string), HashSet<int>> m_ExpandedCompositeBindings;

private readonly InputControlScheme m_ControlScheme;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,9 +659,12 @@ public static List<TreeViewItemData<ActionOrBindingData>> GetActionsAsTreeViewDa

private static int GetIdForGuid(Guid guid, Dictionary<Guid, int> idDictionary)
{
//This method is used to ensure that the same Guid always gets the same id
//We use getHashCode instead of a counter, as we cannot guarantee that the same Guid will always be added in the same order
//There is a tiny chance of a collision, but it is it does happen it will only affect the expanded state of the tree view
if (!idDictionary.TryGetValue(guid, out var id))
{
id = idDictionary.Values.Count > 0 ? idDictionary.Values.Max() + 1 : 0;
id = guid.GetHashCode(); //idDictionary.Values.Count > 0 ? idDictionary.Values.Max() + 1 : 0;
idDictionary.Add(guid, id);
}
return id;
Expand Down
Loading