Ejemplo n.º 1
0
        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 float GetHeight(RuntimeSerializedProperty property, GUIContent label, bool includeChildren)
        {
            float height = 0;

            if (DecoratorDrawers != null && !IsCurrentlyNested)
            {
                foreach (var drawer in DecoratorDrawers)
                {
                    height += drawer.GetHeight();
                }
            }

            if (RuntimePropertyDrawer != null)
            {
                height += RuntimePropertyDrawer.GetPropertyHeightSafe(property, label ?? EditorGUIUtilityHelper.TempContent(property.DisplayName));
            }
            else if (!includeChildren)
            {
                height += RuntimeEasyGUI.GetSinglePropertyHeight(property, label);
            }
            else
            {
                RuntimeSerializedProperty prop = property.Copy();

                // First property with custom label
                height += RuntimeEasyGUI.GetSinglePropertyHeight(prop, label);
                bool childrenAreExpanded = prop.IsExpanded && RuntimeEasyGUI.HasVisibleChildFields(prop);

                // Loop through all child properties
                if (childrenAreExpanded)
                {
                    RuntimeSerializedProperty endProperty = prop.GetEndProperty();
                    while (prop.NextVisible(childrenAreExpanded) && !RuntimeSerializedProperty.EqualContents(prop, endProperty))
                    {
                        height += RuntimeScriptAttributeUtility.GetHandler(prop, null).GetHeight(prop, EditorGUIUtilityHelper.TempContent(prop.DisplayName), true);
                        childrenAreExpanded = false;
                        height += EasyGUI.kControlVerticalSpacing;
                    }
                }
            }

            return(height);
        }
        public void HandleDrawnType(Type drawnType, Type propertyType, FieldInfo field, PropertyAttribute attribute)
        {
            Type drawerType = RuntimeScriptAttributeUtility.GetDrawerTypeForType(drawnType);

            // If we found a drawer type, instantiate the drawer, cache it, and return it.
            if (drawerType != null)
            {
                if (typeof(RuntimePropertyDrawer).IsAssignableFrom(drawerType))
                {
                    // HACK: Here is different from the U3D setting, maybe is not a good idea!
                    // Unity only want use PropertyDrawer on array elements, not on array itself,
                    // But i don't like this setting, so i recode it.
                    runtimePropertyDrawer           = (RuntimePropertyDrawer)Activator.CreateInstance(drawerType);
                    runtimePropertyDrawer.FieldInfo = field;

                    // Will be null by design if default type drawer!
                    runtimePropertyDrawer.Attribute = attribute;
                }
                else if (typeof(UnityEditor.DecoratorDrawer).IsAssignableFrom(drawerType))
                {
                    // Draw decorators on array itself, not on each array elements
                    if (field != null && field.FieldType.IsArrayOrList() && !propertyType.IsArrayOrList())
                    {
                        return;
                    }
                    UnityEditor.DecoratorDrawer decoratorDrawer = (UnityEditor.DecoratorDrawer)Activator.CreateInstance(drawerType);
                    DecoratorDrawerHelper.SetAttribute(decoratorDrawer, attribute);

                    if (DecoratorDrawers == null)
                    {
                        DecoratorDrawers = new List <UnityEditor.DecoratorDrawer>();
                    }
                    DecoratorDrawers.Add(decoratorDrawer);
                }
            }
        }
Ejemplo n.º 4
0
 public static bool PropertyFieldInternal(Rect position, RuntimeSerializedProperty property, GUIContent label, bool includeChildren, List <PropertyAttribute> attributes)
 {
     return(RuntimeScriptAttributeUtility.GetHandler(property, attributes).OnGUI(position, property, label, includeChildren));
 }
Ejemplo n.º 5
0
        public static GenericMenu FillPropertyContextMenu(RuntimeSerializedProperty property, RuntimeSerializedProperty linkedProperty = null)
        {
            GenericMenu popupMenu = new GenericMenu();
            RuntimeSerializedProperty propertyWithPath = property.RuntimeSerializedObject.FindProperty(property.PropertyPath);

            RuntimeScriptAttributeUtility.GetHandler(property, null).AddMenuItems(property, popupMenu);

            if (property.RuntimeSerializedObject.SerializedObject.targetObjects.Length == 1 && property.IsInstantiatedPrefab)
            {
                popupMenu.AddItem(EditorGUIUtility.TrTextContent("Revert Value to Prefab"), false, RuntimeTargetChoiceHandler.RevertPrefabPropertyOverride, propertyWithPath);
            }

            // If property is an element in an array, show duplicate and delete menu options
            if (property.Depth > 0 && !property.PropertyPath.EndsWith("Size"))
            {
                var length     = property.PropertyPath.LastIndexOf(".");
                var parentPath = property.PropertyPath.Substring(0, length);
                var prop       = property.FindProperty(parentPath);

                if (prop != null && prop.IsArray)
                {
                    if (popupMenu.GetItemCount() > 0)
                    {
                        popupMenu.AddSeparator(EmptyStr);
                    }
                    popupMenu.AddItem(EditorGUIUtility.TrTextContent("Duplicate Array Element"), false, (object a) =>
                    {
                        RuntimeTargetChoiceHandler.DuplicateArrayElement(a);
                        EditorGUIUtility.editingTextField = false;
                    }, propertyWithPath);
                    popupMenu.AddItem(EditorGUIUtility.TrTextContent("Delete Array Element"), false, (object a) =>
                    {
                        RuntimeTargetChoiceHandler.DeleteArrayElement(a);
                        EditorGUIUtility.editingTextField = false;
                    }, propertyWithPath);
                }
            }

            // If shift is held down, show debug menu options
            if (Event.current.shift)
            {
                if (popupMenu.GetItemCount() > 0)
                {
                    popupMenu.AddSeparator(EmptyStr);
                }
                popupMenu.AddItem(EditorGUIUtility.TrTextContent("Print Property Path"), false, e => Debug.Log(((SerializedProperty)e).propertyPath), propertyWithPath);
            }
            else
            {
                if (popupMenu.GetItemCount() > 0)
                {
                    popupMenu.AddSeparator(EmptyStr);
                }
                popupMenu.AddItem(EditorGUIUtility.TrTextContent("Copy Component"), false, (object a) =>
                {
                    RuntimeTargetChoiceHandler.CopyComponent(a);
                }, propertyWithPath);
                if (RuntimeTargetChoiceHandler.CanPasteAsNew(propertyWithPath))
                {
                    popupMenu.AddItem(EditorGUIUtility.TrTextContent("Paste Component As New"), false, (object a) =>
                    {
                        RuntimeTargetChoiceHandler.PasteComponentAsNew(a);
                    }, propertyWithPath);
                }
                else
                {
                    popupMenu.AddDisabledItem(EditorGUIUtility.TrTextContent("Paste Component As New"));
                }
                if (RuntimeTargetChoiceHandler.CanPaste(propertyWithPath))
                {
                    popupMenu.AddItem(EditorGUIUtility.TrTextContent("Paste Component Values"), false, (object a) =>
                    {
                        RuntimeTargetChoiceHandler.PasteComponentValues(a);
                    }, propertyWithPath);
                }
                else
                {
                    popupMenu.AddDisabledItem(EditorGUIUtility.TrTextContent("Paste Component Values"));
                }
            }

            if (property.RuntimeSerializedObject.Target != null)
            {
                if (popupMenu.GetItemCount() > 0)
                {
                    popupMenu.AddSeparator(EmptyStr);
                }

                var obj     = propertyWithPath.RuntimeSerializedObject.Target;
                var methods = obj.GetType().GetAllInstanceMethods();

                contextMenuIndex.Clear();
                contextMenuResultIndex.Clear();
                easyContextMenuResultIndex.Clear();

                foreach (var method in methods)
                {
                    foreach (ContextMenu contextMenu in method.GetCustomAttributes(typeof(ContextMenu), false))
                    {
                        contextMenuIndex.Add(contextMenu, method);
                    }
                }
                var orderedContextMenu = contextMenuIndex.Select(kvp => kvp.Key).OrderByDescending(menu => menu.validate).ThenBy(menu => menu.priority).ToArray();
                foreach (var menu in orderedContextMenu)
                {
                    if (menu.validate)
                    {
                        var result = (bool)contextMenuIndex[menu].Invoke(obj, null);
                        if (contextMenuResultIndex.ContainsKey(menu.menuItem))
                        {
                            if (contextMenuResultIndex[menu.menuItem] && !result)
                            {
                                contextMenuResultIndex[menu.menuItem] = result;
                            }
                        }
                        else
                        {
                            contextMenuResultIndex.Add(menu.menuItem, result);
                        }
                    }
                    else
                    {
                        if (contextMenuResultIndex.ContainsKey(menu.menuItem) && !contextMenuResultIndex[menu.menuItem])
                        {
                            popupMenu.AddDisabledItem(EditorGUIUtility.TrTextContent(menu.menuItem));
                        }
                        else
                        {
                            popupMenu.AddItem(EditorGUIUtility.TrTextContent(menu.menuItem), false, (object o) =>
                            {
                                contextMenuIndex[menu].Invoke(o, null);
                            }, obj);
                        }
                    }
                }
            }
            return(popupMenu);
        }
Ejemplo n.º 6
0
 public static float GetPropertyHeightInternal(RuntimeSerializedProperty property, GUIContent label, bool includeChildren, List <PropertyAttribute> attributes)
 {
     return(RuntimeScriptAttributeUtility.GetHandler(property, attributes).GetHeight(property, label, includeChildren));
 }
        public bool OnGUI(Rect position, RuntimeSerializedProperty property, GUIContent label, bool includeChildren, Rect visibleArea)
        {
            float oldLabelWidth, oldFieldWidth;
            float propHeight = position.height;

            position.height = 0;
            if (DecoratorDrawers != null && !IsCurrentlyNested)
            {
                foreach (var decorator in DecoratorDrawers)
                {
                    position.height = decorator.GetHeight();

                    oldLabelWidth = EditorGUIUtility.labelWidth;
                    oldFieldWidth = EditorGUIUtility.fieldWidth;
                    decorator.OnGUI(position);
                    EditorGUIUtility.labelWidth = oldLabelWidth;
                    EditorGUIUtility.fieldWidth = oldFieldWidth;

                    position.y += position.height;
                    propHeight -= position.height;
                }
            }

            position.height = propHeight;
            if (RuntimePropertyDrawer != null)
            {
                // Remember widths
                oldLabelWidth = EditorGUIUtility.labelWidth;
                oldFieldWidth = EditorGUIUtility.fieldWidth;
                // Draw with custom drawer
                RuntimePropertyDrawer.OnGUISafe(position, property, label ?? EditorGUIUtilityHelper.TempContent(property.DisplayName));
                // Restore widths
                EditorGUIUtility.labelWidth = oldLabelWidth;
                EditorGUIUtility.fieldWidth = oldFieldWidth;

                return(false);
            }
            else
            {
                if (!includeChildren)
                {
                    return(RuntimeEasyGUI.DefaultPropertyField(position, property, label));
                }
                // Remember state
                Vector2 oldIconSize = EditorGUIUtility.GetIconSize();
                bool    wasEnabled  = GUI.enabled;
                int     origIndent  = EditorGUI.indentLevel;

                int relIndent = origIndent - property.Depth;

                RuntimeSerializedProperty prop = property.Copy();

                position.height = RuntimeEasyGUI.GetSinglePropertyHeight(property, label);

                // First property with custom label
                EditorGUI.indentLevel = property.Depth + relIndent;
                bool childrenAreExpanded = RuntimeEasyGUI.DefaultPropertyField(position, property, label) && RuntimeEasyGUI.HasVisibleChildFields(property);
                position.y += position.height + EasyGUI.kControlVerticalSpacing;

                // Loop through all child properties
                if (childrenAreExpanded)
                {
                    RuntimeSerializedProperty endProperty = property.GetEndProperty();
                    while (prop.NextVisible(childrenAreExpanded) && !RuntimeSerializedProperty.EqualContents(prop, endProperty))
                    {
                        var handler = RuntimeScriptAttributeUtility.GetHandler(prop, null);
                        EditorGUI.indentLevel = prop.Depth + relIndent;
                        position.height       = handler.GetHeight(prop, null, false);

                        if (position.Overlaps(visibleArea))
                        {
                            EditorGUI.BeginChangeCheck();
                            childrenAreExpanded = handler.OnGUI(position, prop, null, false) && RuntimeEasyGUI.HasVisibleChildFields(prop);
                            // Changing child properties (like array size) may invalidate the iterator,
                            // so stop now, or we may get errors.
                            if (EditorGUI.EndChangeCheck())
                            {
                                break;
                            }
                        }

                        position.y += position.height + EasyGUI.kControlVerticalSpacing;
                    }
                }

                // Restore state
                GUI.enabled = wasEnabled;
                EditorGUIUtility.SetIconSize(oldIconSize);
                EditorGUI.indentLevel = origIndent;

                return(false);
            }
        }