#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR using System; using System.Linq; using UnityEditor; using UnityEngine.UIElements; namespace UnityEngine.InputSystem.Editor { internal class PropertiesView : ViewBase { private readonly VisualElement m_Root; private ActionPropertiesView m_ActionPropertyView; private BindingPropertiesView m_BindingPropertyView; private NameAndParametersListView m_InteractionsListView; private NameAndParametersListView m_ProcessorsListView; private Foldout interactionsFoldout => m_Root.Q("interactions-foldout"); private Foldout processorsFoldout => m_Root.Q("processors-foldout"); private TextElement addInteractionButton; private TextElement addProcessorButton; public PropertiesView(VisualElement root, StateContainer stateContainer) : base(stateContainer) { m_Root = root; CreateSelector( Selectors.GetSelectedAction, Selectors.GetSelectedBinding, state => state.selectionType, (inputAction, inputBinding, selectionType, s) => new ViewState() { selectionType = selectionType, serializedInputAction = inputAction, inputBinding = inputBinding, relatedInputAction = Selectors.GetRelatedInputAction(s) }); var interactionsToggle = interactionsFoldout.Q(); interactionsToggle.AddToClassList("properties-foldout-toggle"); if (addInteractionButton == null) { addInteractionButton = CreateAddButton(interactionsToggle, "add-new-interaction-button"); new ContextualMenuManipulator(_ => {}){target = addInteractionButton, activators = {new ManipulatorActivationFilter(){button = MouseButton.LeftMouse}}}; } var processorToggle = processorsFoldout.Q(); processorToggle.AddToClassList("properties-foldout-toggle"); if (addProcessorButton == null) { addProcessorButton = CreateAddButton(processorToggle, "add-new-processor-button"); new ContextualMenuManipulator(_ => {}){target = addProcessorButton, activators = {new ManipulatorActivationFilter(){button = MouseButton.LeftMouse}}}; } } private TextElement CreateAddButton(Toggle toggle, string name) { var addButton = new Button(); addButton.text = "+"; addButton.name = name; addButton.focusable = false; #if UNITY_EDITOR_OSX addButton.clickable.activators.Clear(); #endif addButton.AddToClassList("add-interaction-processor-button"); toggle.Add(addButton); return addButton; } private void CreateContextMenuProcessor(string expectedControlType) { var processors = InputProcessor.s_Processors; Type expectedValueType = string.IsNullOrEmpty(expectedControlType) ? null : EditorInputControlLayoutCache.GetValueType(expectedControlType); addProcessorButton.RegisterCallback(evt => { evt.menu.ClearItems(); foreach (var name in processors.internedNames.Where(x => !processors.ShouldHideInUI(x)).OrderBy(x => x.ToString())) { // Skip if not compatible with value type. if (!IsValidProcessorForControl(expectedValueType, name)) continue; var niceName = ObjectNames.NicifyVariableName(name); evt.menu.AppendAction(niceName, _ => m_ProcessorsListView.OnAddElement(name.ToString())); } }); } private bool IsValidProcessorForControl(Type expectedValueType, string name) { if (expectedValueType == null) return true; var type = InputProcessor.s_Processors.LookupTypeRegistration(name); var valueType = InputProcessor.GetValueTypeFromType(type); if (valueType != null && !expectedValueType.IsAssignableFrom(valueType)) return false; return true; } private void CreateContextMenuInteraction(string expectedControlType) { var interactions = InputInteraction.s_Interactions; Type expectedValueType = string.IsNullOrEmpty(expectedControlType) ? null : EditorInputControlLayoutCache.GetValueType(expectedControlType); addInteractionButton.RegisterCallback(evt => { evt.menu.ClearItems(); foreach (var name in interactions.internedNames.Where(x => !interactions.ShouldHideInUI(x)).OrderBy(x => x.ToString())) { // Skip if not compatible with value type. if (!IsValidInteractionForControl(expectedValueType, name)) continue; var niceName = ObjectNames.NicifyVariableName(name); evt.menu.AppendAction(niceName, _ => m_InteractionsListView.OnAddElement(name.ToString())); } }); } private bool IsValidInteractionForControl(Type expectedValueType, string name) { if (expectedValueType == null) return true; var type = InputInteraction.s_Interactions.LookupTypeRegistration(name); var valueType = InputInteraction.GetValueType(type); if (valueType != null && !expectedValueType.IsAssignableFrom(valueType)) return false; return true; } public override void RedrawUI(ViewState viewState) { DestroyChildView(m_ActionPropertyView); DestroyChildView(m_BindingPropertyView); DestroyChildView(m_InteractionsListView); DestroyChildView(m_ProcessorsListView); var propertiesContainer = m_Root.Q("properties-container"); var foldout = propertiesContainer.Q("properties-foldout"); foldout.Clear(); var visualElement = new VisualElement(); foldout.Add(visualElement); foldout.Q().AddToClassList("properties-foldout-toggle"); var inputAction = viewState.serializedInputAction; var inputActionOrBinding = inputAction?.wrappedProperty; switch (viewState.selectionType) { case SelectionType.Action: m_Root.Q