public virtual void OnAfterDeserialize() { m_Main = SerializationHelper.DeserializeObj <ControlReferenceBinding <ButtonControl, float> >(m_SerializedMain, new object[] {}); m_Modifiers = SerializationHelper.Deserialize <ControlReferenceBinding <ButtonControl, float> >(m_SerializedModifiers, new object[] {}); m_ModifierSet = SerializationHelper.Deserialize <ControlReferenceBinding <ButtonControl, float> >(m_SerializedModifierSet, new object[] {}); m_SerializedMain = new SerializationHelper.JSONSerializedElement(); m_SerializedModifiers = null; m_SerializedModifierSet = null; }
public override object Clone() { var clone = new ControlReferenceBinding <C, T>(); clone.m_SourceControl = m_SourceControl; clone.m_ControlHash = m_ControlHash; clone.m_DeviceKey = m_DeviceKey; return(clone); }
public override void OnGUI(Rect position, IControlDomainSource domainSource) { position.height = ControlGUIUtility.GetControlHeight(m_Main, s_MainContent); ControlGUIUtility.ControlField(position, m_Main, s_MainContent, domainSource, b => m_Main = b as ControlReferenceBinding <ButtonControl, float>); position.y += position.height + EditorGUIUtility.standardVerticalSpacing; position.height = EditorGUIUtility.singleLineHeight; EditorGUI.BeginChangeCheck(); int count = EditorGUI.IntField(position, s_CountContent, modifiers.Count); if (EditorGUI.EndChangeCheck()) { if (count > modifiers.Count) { while (modifiers.Count < count) { modifiers.Add(null); } } else { modifiers.RemoveRange(count, modifiers.Count - count); } } for (int i = 0; i < modifiers.Count; i++) { int index = i; // See "close over the loop variable". var control = modifiers[i]; position.y += position.height + EditorGUIUtility.standardVerticalSpacing; position.height = ControlGUIUtility.GetControlHeight(control, s_ModifierContent); ControlGUIUtility.ControlField(position, control, s_ModifierContent, domainSource, b => modifiers[index] = b as ControlReferenceBinding <ButtonControl, float>); } position.y += position.height + EditorGUIUtility.standardVerticalSpacing; position.height = EditorGUIUtility.singleLineHeight; EditorGUI.BeginChangeCheck(); count = EditorGUI.IntField(position, s_CountContent, modifierSet.Count); if (EditorGUI.EndChangeCheck()) { if (count > modifierSet.Count) { while (modifierSet.Count < count) { modifierSet.Add(null); } } else { modifierSet.RemoveRange(count, modifierSet.Count - count); } } for (int i = 0; i < modifierSet.Count; i++) { int index = i; // See "close over the loop variable". var control = modifierSet[i]; position.y += position.height + EditorGUIUtility.standardVerticalSpacing; position.height = ControlGUIUtility.GetControlHeight(control, s_ModifierContent); ControlGUIUtility.ControlField(position, control, s_ModifierContent, domainSource, b => modifierSet[index] = b as ControlReferenceBinding <ButtonControl, float>); } }
static GenericMenu GetMenu <C, T>(InputBinding <C, T> binding, IControlDomainSource domainSource, Action <InputBinding <C, T> > action) where C : InputControl <T> { GenericMenu menu = new GenericMenu(); Type[] derivedTypes = null; string[] derivedNames = null; Dictionary <Type, int> indicesOfDerivedTypes = null; TypeGUI.GetDerivedTypesInfo(typeof(InputBinding <C, T>), out derivedTypes, out derivedNames, out indicesOfDerivedTypes); Type bindingType = typeof(ControlReferenceBinding <C, T>); Type existingType = binding == null ? null : binding.GetType(); var reference = binding as ControlReferenceBinding <C, T>; // Add control references for devices. bool hasReferences = false; if (derivedTypes.Contains(bindingType)) { hasReferences = true; List <DomainEntry> domainEntries = domainSource.GetDomainEntries(); for (int i = 0; i < domainEntries.Count; i++) { int domainHash = domainEntries[i].hash; List <DomainEntry> controlEntries = domainSource.GetControlEntriesOfType(domainHash, typeof(C)); bool showFlatList = (domainEntries.Count <= 1 && controlEntries.Count <= 20); string prefix = showFlatList ? string.Empty : domainEntries[i].name + "/"; bool nonStandardizedSectionStart = false; for (int j = 0; j < controlEntries.Count; j++) { bool selected = (reference != null && reference.deviceKey == domainHash && reference.controlHash == controlEntries[j].hash); if (!nonStandardizedSectionStart && !controlEntries[j].standardized) { nonStandardizedSectionStart = true; menu.AddSeparator(prefix); } GUIContent name = new GUIContent(prefix + controlEntries[j].name); int index = j; // See "close over the loop variable". menu.AddItem(name, selected, () => { var newReference = new ControlReferenceBinding <C, T>(); newReference.deviceKey = domainHash; newReference.controlHash = controlEntries[index].hash; action(newReference); }); } } } if (derivedTypes.Length <= (hasReferences ? 1 : 0)) { return(menu); } menu.AddSeparator(""); // Add other control types. for (int i = 0; i < derivedTypes.Length; i++) { if (derivedTypes[i] != bindingType) { bool selected = (existingType == derivedTypes[i]); string name = NicifyBindingName(derivedNames[i]); int index = i; // See "close over the loop variable". menu.AddItem(new GUIContent(name), selected, () => { var newBinding = Activator.CreateInstance(derivedTypes[index]) as InputBinding <C, T>; action(newBinding); }); } } return(menu); }
public static void ControlField <C, T>(Rect position, InputBinding <C, T> binding, GUIContent label, IControlDomainSource domainSource, Action <InputBinding <C, T> > action, SerializedProperty prop = null) where C : InputControl <T> { if (prop != null) { label = EditorGUI.BeginProperty(position, label, prop); } position.height = EditorGUIUtility.singleLineHeight; Rect buttonPosition = EditorGUI.PrefixLabel(position, label); Rect detectPosition = buttonPosition; ControlScheme scheme = domainSource as ControlScheme; bool detectionSupport = (scheme != null); if (detectionSupport) { detectPosition.xMin = detectPosition.xMax - 20; buttonPosition.xMax -= (20 + 4); } if (EditorGUI.DropdownButton(buttonPosition, new GUIContent(GetName(binding, domainSource) ?? "None"), FocusType.Keyboard)) { GenericMenu menu = GetMenu( binding, domainSource, a => { if (prop != null) { Undo.RecordObjects(prop.serializedObject.targetObjects, "Control"); } action(a); if (prop != null) { // Flushing seems necessaary to have prefab property override status change without lag. Undo.FlushUndoRecordObjects(); prop.serializedObject.SetIsDifferentCacheDirty(); } }); menu.DropDown(buttonPosition); // GenericMenu doesn't modify GUI.changed because it relies on a callback, so let's assume that something was changed, so target object dirtying doesn't go missing GUI.changed = true; } if (detectionSupport) { EditorGUI.BeginDisabledGroup(s_Binding != null); //if (Event.current.type == EventType.repaint) // EditorStyles.miniButton.Draw(detectPosition, "O", false, false, s_Binding == binding, false); if (GUI.Toggle(detectPosition, s_Binding == binding, "O", EditorStyles.miniButton) && s_Binding == null) { EditorWindow window = EditorWindow.focusedWindow; window.ShowNotification(new GUIContent("Waiting for input.")); s_BindingListener = (InputControl control) => { if (!(control is C)) { window.ShowNotification(new GUIContent("Incompatible control type.")); window.Repaint(); return(false); } DeviceSlot match = null; Type controlProviderType = control.provider.GetType(); for (int slotIndex = 0; slotIndex < scheme.deviceSlots.Count; slotIndex++) { Type deviceType = scheme.deviceSlots[slotIndex].type.value; if (deviceType == null) { continue; } if (deviceType.IsAssignableFrom(controlProviderType)) { match = scheme.deviceSlots[slotIndex]; break; } } if (match == null) { window.ShowNotification(new GUIContent("Incompatible device type.")); window.Repaint(); return(false); } var newReference = new ControlReferenceBinding <C, T>(); newReference.deviceKey = match.key; newReference.controlHash = control.provider.GetHashForControlIndex(control.index); action(newReference); StopListening(window); return(true); }; InputSystem.ListenForBinding(s_BindingListener); s_Binding = binding; float time = Time.realtimeSinceStartup; s_UpdateCallback = () => { if (Time.realtimeSinceStartup > time + 3) { StopListening(window); } }; EditorApplication.update += s_UpdateCallback; } EditorGUI.EndDisabledGroup(); } if (binding != null && !(binding is ControlReferenceBinding <C, T>)) { EditorGUI.indentLevel++; position.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; binding.OnGUI(position, domainSource); EditorGUI.indentLevel--; } if (prop != null) { EditorGUI.EndProperty(); } }
public override void OnGUI(Rect position, IControlDomainSource domainSource) { // Bindings for (int i = 0; i < sources.Count; i++) { InputBinding <C, T> source = sources[i]; position.height = ControlGUIUtility.GetControlHeight(source, Styles.bindingContent); DrawSourceSettings(position, i, domainSource); position.y += position.height + EditorGUIUtility.standardVerticalSpacing; } // Bindings remove and add buttons position.height = EditorGUIUtility.singleLineHeight; Rect buttonPosition = position; buttonPosition.width = Styles.iconToolbarMinus.image.width; if (GUI.Button(buttonPosition, Styles.iconToolbarMinus, GUIStyle.none)) { var selected = m_Selected as InputBinding <C, T>; if (sources.Contains(selected)) { sources.Remove(selected); } } buttonPosition.x += buttonPosition.width; if (GUI.Button(buttonPosition, Styles.iconToolbarPlus, GUIStyle.none)) { var source = new ControlReferenceBinding <C, T>(); sources.Add(source); m_Selected = source; } position.y += position.height + Styles.k_Spacing; position.height = EditorGUIUtility.singleLineHeight; GUI.Label(position, "Processors"); position.y += position.height + Styles.k_Spacing; // Processors for (int i = 0; i < processors.Count; i++) { InputBindingProcessor <C, T> processor = processors[i]; position.height = processor.GetPropertyHeight(); DrawProcessorSettings(position, i); position.y += position.height + EditorGUIUtility.standardVerticalSpacing; } // Processors remove and add buttons position.height = EditorGUIUtility.singleLineHeight; buttonPosition = position; buttonPosition.width = Styles.iconToolbarMinus.image.width; if (GUI.Button(buttonPosition, Styles.iconToolbarMinus, GUIStyle.none)) { var selected = m_Selected as InputBindingProcessor <C, T>; if (selected != null && processors.Contains(selected)) { processors.Remove(selected); } } buttonPosition.x += buttonPosition.width; if (GUI.Button(buttonPosition, Styles.iconToolbarPlus, GUIStyle.none)) { InputBindingProcessor <C, T> .ShowAddProcessorDropdown(buttonPosition, p => processors.Add(p)); } }