public static GUIContent BeginProperty(Rect totalPosition, GUIContent label, RuntimeSerializedProperty property) { Highlighter.HighlightIdentifier(totalPosition, property.PropertyPath); if (s_PendingPropertyKeyboardHandling != null) { DoPropertyFieldKeyboardHandling(s_PendingPropertyKeyboardHandling); } // Properties can be nested, so A BeginProperty may not be followed by its corresponding EndProperty // before there have been one or more pairs of BeginProperty/EndProperty in between. // The keyboard handling for a property (that handles duplicate and delete commands for array items) // uses EditorGUI.lastControlID so it has to be executed for a property before any possible child // properties are handled. However, it can't be done in it's own BeginProperty, because the controlID // for the property is not yet known at that point. For that reason we mark the keyboard handling as // pending and handle it either the next BeginProperty call (for the first child property) or if there's // no child properties, then in the matching EndProperty call. s_PendingPropertyKeyboardHandling = property; if (property == null) { string error = ((label != null) ? (label.text + ": ") : EmptyStr) + "RuntimeSerializedProperty is null"; EditorGUI.HelpBox(totalPosition, "null", MessageType.Error); throw new System.NullReferenceException(error); } s_PropertyFieldTempContent.text = LocalizationDatabaseHelper.GetLocalizedString((label != null) ? label.text : property.DisplayName); // no necessary to be translated. s_PropertyFieldTempContent.tooltip = EasyGUI.IsCollectingTooltips ? ((label == null) ? property.Tooltip : label.tooltip) : null; string attributeTooltip = RuntimeScriptAttributeUtility.GetHandler(property, null).Tooltip; if (attributeTooltip != null) { s_PropertyFieldTempContent.tooltip = attributeTooltip; } s_PropertyFieldTempContent.image = label != null ? label.image : null; // In inspector debug mode & when holding down alt. Show the property path of the property. if (Event.current.alt && property.RuntimeSerializedObject.SerializedObject.InspectorMode() != InspectorMode.Normal) { s_PropertyFieldTempContent.tooltip = s_PropertyFieldTempContent.text = property.PropertyPath; } bool wasBoldDefaultFont = EditorGUIUtilityHelper.GetBoldDefaultFont(); if (property.RuntimeSerializedObject.SerializedObject.targetObjects.Length == 1 && property.IsInstantiatedPrefab) { EditorGUIUtilityHelper.SetBoldDefaultFont(property.PrefabOverride); } s_PropertyStack.Push(new RuntimePropertyGUIData(property, totalPosition, wasBoldDefaultFont, GUI.enabled, GUI.backgroundColor)); GUI.enabled &= property.Editable; return(s_PropertyFieldTempContent); }
public static void EndProperty() { EditorGUI.showMixedValue = false; RuntimePropertyGUIData data = s_PropertyStack.Pop(); // Context menu // Handle context menu in EndProperty instead of BeginProperty. This ensures that child properties // get the event rather than parent properties when clicking inside the child property rects, but the menu can // still be invoked for the parent property by clicking inside the parent rect but outside the child rects. if (Event.current.type == EventType.ContextClick && data.TotalPosition.Contains(Event.current.mousePosition)) { DoPropertyContextMenu(data.Property); } EditorGUIUtilityHelper.SetBoldDefaultFont(data.WasBoldDefaultFont); GUI.enabled = data.WasEnabled; GUI.backgroundColor = data.Color; if (s_PendingPropertyKeyboardHandling != null) { DoPropertyFieldKeyboardHandling(s_PendingPropertyKeyboardHandling); } // Wait with deleting the property until the property stack is empty in order to avoid // deleting a property in the middle of GUI calls that's dependent on it existing. if (s_PendingPropertyDelete != null && s_PropertyStack.Count == 0) { // For SerializedProperty iteration reasons, if the property we delete is the current property, // we have to delete on the actual iterator property rather than a copy of it, // otherwise we get an error next time we call NextVisible on the iterator property. if (s_PendingPropertyDelete.PropertyPath == data.Property.PropertyPath) { data.Property.DeleteCommand(); } else { s_PendingPropertyDelete.DeleteCommand(); } s_PendingPropertyDelete = null; } }