diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index 2813c56348..5793f3dbf8 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Removed 32-bit compilation check for HID on Windows players, which had no impact anymore. (ISX-2543) - Migrated sample scenes to use Universal Render Pipeline (URP) with Built-in Render Pipeline fallback shaders. The URP package is now required to run the samples. (ISX-2343) - Changed the UI for `Actions.inputactions` asset to use UI Toolkit framework. +- Changed the UI for `InputSystem.inputsettings` asset to use UI Toolkit framework. ### Added diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/InputAssetEditorUtils.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/InputAssetEditorUtils.cs index e9aede7015..d89bddb695 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/InputAssetEditorUtils.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/InputAssetEditorUtils.cs @@ -3,6 +3,7 @@ using System; using System.IO; using UnityEditor; +using UnityEngine.UIElements; namespace UnityEngine.InputSystem.Editor { @@ -19,7 +20,7 @@ internal enum DialogResult InvalidPath, /// - /// The dialog was cancelled by the user and the path is invalid. + /// The dialog was canceled by the user and the path is invalid. /// Cancelled, @@ -82,12 +83,32 @@ internal static T CreateAsset(T asset, string relativePath) where T : Scripta return asset; } - public static void DrawMakeActiveGui(T current, T target, string targetName, string entity, Action apply, bool allowAssignActive = true) + public static VisualElement CreateMakeActiveGui(Func getCurrent, T target, string targetName, string entity, + Action apply, Action subscribeToChanges, Action unsubscribeFromChanges, + bool allowAssignActive = true) where T : ScriptableObject { + var container = new VisualElement(); + + void Refresh() => PopulateMakeActiveGui(container, getCurrent(), target, entity, apply, allowAssignActive); + + Refresh(); + + // Subscribe for as long as the element is part of a panel, matching the pattern used in InputParameterEditor. + container.RegisterCallback(_ => subscribeToChanges(Refresh)); + container.RegisterCallback(_ => unsubscribeFromChanges(Refresh)); + + return container; + } + + private static void PopulateMakeActiveGui(VisualElement container, T current, T target, string entity, Action apply, bool allowAssignActive) + where T : ScriptableObject + { + container.Clear(); + if (current == target) { - EditorGUILayout.HelpBox($"These actions are assigned as the {entity}.", MessageType.Info); + container.Add(new HelpBox($"These actions are assigned as the {entity}.", HelpBoxMessageType.Info)); return; } @@ -96,11 +117,21 @@ public static void DrawMakeActiveGui(T current, T target, string targetName, currentlyActiveAssetsPath = AssetDatabase.GetAssetPath(current); if (!string.IsNullOrEmpty(currentlyActiveAssetsPath)) currentlyActiveAssetsPath = $" The actions currently assigned as the {entity} are: {currentlyActiveAssetsPath}. "; - EditorGUILayout.HelpBox($"These actions are not assigned as the {entity} for the Input System. {currentlyActiveAssetsPath??""}", MessageType.Warning); - GUI.enabled = allowAssignActive; - if (GUILayout.Button($"Assign as the {entity}", EditorStyles.miniButton)) + + container.Add(new HelpBox( + $"These actions are not assigned as the {entity} for the Input System. {currentlyActiveAssetsPath ?? ""}", + HelpBoxMessageType.Warning)); + + var assignButton = new Button(() => + { apply(target); - GUI.enabled = true; + PopulateMakeActiveGui(container, target, target, entity, apply, allowAssignActive); + }) + { + text = $"Assign as the {entity}" + }; + assignButton.SetEnabled(allowAssignActive); + container.Add(assignButton); } public static bool IsValidFileExtension(string path) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs index 1ac676a022..cb21d46051 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs @@ -489,17 +489,36 @@ internal static void ForceReload() [CustomEditor(typeof(InputSettings))] internal class InputSettingsEditor : UnityEditor.Editor { - public override void OnInspectorGUI() + public override VisualElement CreateInspectorGUI() { - EditorGUILayout.Space(); + var root = new VisualElement(); - if (GUILayout.Button("Open Input Settings Window", GUILayout.Height(30))) - InputSettingsProvider.Open(); - - EditorGUILayout.Space(); + var openButton = new Button(() => InputSettingsProvider.Open()) + { + text = "Open Input Settings Window", + style = { minHeight = 30, whiteSpace = WhiteSpace.Normal } + }; + root.Add(openButton); + + // UndoRedoCallback is void(), not Action, so an adapter is required. + // The variable is shared between the two lambdas so the same instance is removed on unsubscribe. + Undo.UndoRedoCallback undoRedoAdapter = null; + root.Add(InputAssetEditorUtils.CreateMakeActiveGui( + () => InputSystem.settings, target as InputSettings, + target.name, "settings", (value) => InputSystem.settings = value, + handler => + { + InputSystem.onSettingsChange += handler; + undoRedoAdapter = () => handler(); + Undo.undoRedoPerformed += undoRedoAdapter; + }, + handler => + { + InputSystem.onSettingsChange -= handler; + Undo.undoRedoPerformed -= undoRedoAdapter; + })); - InputAssetEditorUtils.DrawMakeActiveGui(InputSystem.settings, target as InputSettings, - target.name, "settings", (value) => InputSystem.settings = value); + return root; } protected override bool ShouldHideOpenButton()