public InputBindingPropertiesView( SerializedProperty bindingProperty, Action <FourCC> onChange = null, InputControlPickerState controlPickerState = null, string expectedControlLayout = null, ReadOnlyArray <InputControlScheme> controlSchemes = new ReadOnlyArray <InputControlScheme>(), IEnumerable <string> controlPathsToMatch = null) : base(InputActionSerializationHelpers.IsCompositeBinding(bindingProperty) ? "Composite" : "Binding", bindingProperty, onChange, expectedControlLayout) { m_BindingProperty = bindingProperty; m_GroupsProperty = bindingProperty.FindPropertyRelative("m_Groups"); m_PathProperty = bindingProperty.FindPropertyRelative("m_Path"); m_BindingGroups = m_GroupsProperty.stringValue.Split(InputBinding.Separator).ToList(); m_ExpectedControlLayout = expectedControlLayout; m_ControlSchemes = controlSchemes; var flags = (InputBinding.Flags)bindingProperty.FindPropertyRelative("m_Flags").intValue; m_IsPartOfComposite = (flags & InputBinding.Flags.PartOfComposite) != 0; m_IsComposite = (flags & InputBinding.Flags.Composite) != 0; // Set up control picker for m_Path. Not needed if the binding is a composite. if (!m_IsComposite) { m_ControlPickerState = controlPickerState ?? new InputControlPickerState(); m_ControlPathEditor = new InputControlPathEditor(m_PathProperty, m_ControlPickerState, OnPathChanged); m_ControlPathEditor.SetExpectedControlLayout(m_ExpectedControlLayout); if (controlPathsToMatch != null) { m_ControlPathEditor.SetControlPathsToMatch(controlPathsToMatch); } } }
private void OnItemDoubleClicked(ActionTreeItemBase item) { // Double-clicking on binding or action item opens property popup. PropertiesViewBase propertyView = null; if (item is BindingTreeItem) { if (m_ControlPickerState == null) { m_ControlPickerState = new InputControlPickerState(); } propertyView = new InputBindingPropertiesView(item.property, controlPickerState: m_ControlPickerState, expectedControlLayout: item.expectedControlLayout, onChange: change => m_TreeView.Reload()); } else if (item is ActionTreeItem) { propertyView = new InputActionPropertiesView(item.property, onChange: change => m_TreeView.Reload()); } if (propertyView != null) { var rect = new Rect(GUIUtility.GUIToScreenPoint(Event.current.mousePosition), Vector2.zero); PropertiesViewPopup.Show(rect, propertyView); } }
/// <summary> /// Initialize the control path editor. /// </summary> /// <param name="pathProperty"><see cref="string"/> type property that will receive the picked input control path.</param> /// <param name="pickerState">Persistent editing state of the path editor. Used to retain state across domain reloads.</param> /// <param name="onModified">Delegate that is called when the path has been modified.</param> /// <param name="label">Optional label to display instead of display name of <paramref name="pathProperty"/>.</param> /// <exception cref="ArgumentNullException"><paramref name="pathProperty"/> is <c>null</c>.</exception> public InputControlPathEditor(SerializedProperty pathProperty, InputControlPickerState pickerState, Action onModified, GUIContent label = null) { if (pathProperty == null) { throw new ArgumentNullException(nameof(pathProperty)); } this.pathProperty = pathProperty; this.onModified = onModified; m_PickerState = pickerState ?? new InputControlPickerState(); m_PathLabel = label ?? new GUIContent(pathProperty.displayName, pathProperty.GetTooltip()); }
/// <summary> /// /// </summary> /// <param name="pathProperty"><see cref="string"/> type property that will receive the picked input control path.</param> /// <param name="pickerState">Persistent editing state of the </param> /// <param name="onModified"></param> /// <exception cref="ArgumentNullException"></exception> public InputControlPathEditor(SerializedProperty pathProperty, InputControlPickerState pickerState, Action onModified) { if (pathProperty == null) { throw new ArgumentNullException(nameof(pathProperty)); } this.pathProperty = pathProperty; this.onModified = onModified; m_PickerState = pickerState ?? new InputControlPickerState(); }
public InputControlPickerDropdown( InputControlPickerState state, Action <string> onPickCallback, InputControlPicker.Mode mode = InputControlPicker.Mode.PickControl) : base(state.advancedDropdownState) { m_Gui = new InputControlPickerGUI(this); minimumSize = new Vector2(275, 300); maximumSize = new Vector2(0, 300); m_OnPickCallback = onPickCallback; m_Mode = mode; }
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { if (m_PickerState == null) { m_PickerState = new InputControlPickerState(); } if (m_Editor == null) { m_Editor = new InputControlPathEditor(property, m_PickerState, () => property.serializedObject.ApplyModifiedProperties()); m_Editor.SetExpectedControlLayoutFromAttribute(); } EditorGUI.BeginProperty(position, label, property); m_Editor.OnGUI(position); EditorGUI.EndProperty(); }
private void LoadPropertiesForSelection() { m_BindingPropertyView = null; m_ActionPropertyView = null; ////TODO: preserve interaction/processor selection when reloading // Nothing else to do if we don't have a selection in the middle pane or if // multiple items are selected (we don't currently have the ability to multi-edit). if (!m_ActionsTree.HasSelection() || m_ActionsTree.GetSelection().Count != 1) { return; } var item = m_ActionsTree.GetSelectedItems().FirstOrDefault(); if (item is BindingTreeItem) { // Grab the action for the binding and see if we have an expected control layout // set on it. Pass that on to the control picking machinery. var isCompositePartBinding = item is PartOfCompositeBindingTreeItem; var isCompositeBinding = item is CompositeBindingTreeItem; var actionItem = (isCompositePartBinding ? item.parent.parent : item.parent) as ActionTreeItem; Debug.Assert(actionItem != null); if (m_ControlPickerViewState == null) { m_ControlPickerViewState = new InputControlPickerState(); } // The toolbar may constrain the set of devices we're currently interested in by either // having one specific device selected from the current scheme or having at least a control // scheme selected. var controlPathsToMatch = (IEnumerable <string>)null; if (m_Toolbar.selectedDeviceRequirement != null) { // Single device selected from set of devices in control scheme. controlPathsToMatch = new[] { m_Toolbar.selectedDeviceRequirement.Value.controlPath }; } else if (m_Toolbar.selectedControlScheme != null) { // Constrain to devices from current control scheme. controlPathsToMatch = m_Toolbar.selectedControlScheme.Value.deviceRequirements.Select(x => x.controlPath); } else { // If there's no device filter coming from a control scheme, filter by supported // devices as given by settings. controlPathsToMatch = InputSystem.settings.supportedDevices; } // Show properties for binding. m_BindingPropertyView = new InputBindingPropertiesView( item.property, change => { if (change == InputBindingPropertiesView.k_PathChanged || change == InputBindingPropertiesView.k_CompositePartAssignmentChanged || change == InputBindingPropertiesView.k_CompositeTypeChanged) { ApplyAndReloadTrees(); } else { // Simple property change that doesn't affect the rest of the UI. Apply(); } }, m_ControlPickerViewState, expectedControlLayout: item.expectedControlLayout, controlSchemes: m_Toolbar.controlSchemes, controlPathsToMatch: controlPathsToMatch); } else if (item is ActionTreeItem actionItem) { // Show properties for action. m_ActionPropertyView = new InputActionPropertiesView( actionItem.property, // Apply without reload is enough here as modifying the properties of an action will // never change the structure of the data. change => Apply()); } }
public InputControlPicker(Mode mode, Action <string> onPick, InputControlPickerState state) { m_State = state ?? new InputControlPickerState(); m_Dropdown = new InputControlPickerDropdown(state, onPick, mode: mode); }