public override bool CanProcessForProperty(InspectorProperty property)
 {
     return(this.GetClassDefinedTypeInfoBox(property) != null);
 }
Beispiel #2
0
 /// <summary>
 /// Gets a unique key for any given property within a drawer.
 /// </summary>
 /// <param name="property">The property.</param>
 /// <param name="drawer">The drawer.</param>
 /// <returns></returns>
 public static UniqueDrawerKey Create(InspectorProperty property, OdinDrawer drawer)
 {
     return(new UniqueDrawerKey(property, drawer));
 }
Beispiel #3
0
 public ListDrawerChain(InspectorProperty property, IList <OdinDrawer> list)
     : base(property)
 {
     this.list = list;
 }
Beispiel #4
0
 public BakedDrawerChain(InspectorProperty property, IEnumerable <OdinDrawer> chain)
     : base(property)
 {
     this.bakedDrawerChain = chain.ToArray();
 }
        internal static InspectorProperty Create(PropertyTree tree, InspectorProperty parent, InspectorPropertyInfo info, int index)
        {
            // Validate parameters first
            if (tree == null)
            {
                throw new ArgumentNullException("tree");
            }

            if (info == null)
            {
                if (parent == null)
                {
                    throw new ArgumentException("A parent is expected when the given InspectorPropertyInfo is null.");
                }

                if (parent.Children.IsCollection == false)
                {
                    throw new ArgumentException("The children of the given parent must be from a collection when the given InspectorPropertyInfo is null.");
                }
            }

            if (parent != null)
            {
                if (tree != parent.Tree)
                {
                    throw new ArgumentException("The given tree and the given parent's tree are not the same tree.");
                }

                if (parent.Children is DisabledPropertyChildren)
                {
                    throw new ArgumentException("A given parent must be able to have children to create a child property for it.");
                }

                if (index < 0 || index >= parent.Children.Count)
                {
                    throw new IndexOutOfRangeException("The given index for the property to create is out of bounds.");
                }
            }
            else
            {
                index = -1;
            }

            // Now start building a property
            InspectorProperty property = new InspectorProperty();

            property.Tree = tree;

            if (parent != null)
            {
                property.Path = parent.Children.GetPath(index);
            }
            else
            {
                property.Path = info.PropertyName;
            }

            property.Parent = parent;

            property.Index   = index;
            property.Context = new PropertyContextContainer(property);

            if (property.Path == null)
            {
                Debug.Log("Property path is null for property " + property.NiceName + "!");
            }

            {
                InspectorProperty current = property;

                do
                {
                    current = current.Parent;
                }while (current != null && current.BaseValueEntry == null);

                property.ParentValueProperty = current;
            }

            if (property.ParentValueProperty != null)
            {
                property.ParentType   = property.ParentValueProperty.ValueEntry.TypeOfValue;
                property.ParentValues = new ImmutableList(property.ParentValueProperty.ValueEntry.WeakValues);
            }
            else
            {
                property.ParentType   = tree.TargetType;
                property.ParentValues = new ImmutableList(tree.WeakTargets);
            }

            if (info != null)
            {
                property.Info     = info;
                property.Name     = info.PropertyName;
                property.NiceName = ObjectNames.NicifyVariableName(property.Name.TrimStart('#'));
                property.Label    = new GUIContent(property.NiceName);
            }
            else
            {
                // Collection elements inherit the info of the collection itself
                // and have their name set a little further down
                property.Info = parent.Info;
            }

            if (property.Info.PropertyType == PropertyType.ValueType || property.Info.PropertyType == PropertyType.ReferenceType)
            {
                property.BaseValueEntry = PropertyValueEntry.Create(property, InspectorProperty.GetBaseContainedValueType(property));
                property.ValueEntry     = property.BaseValueEntry;
            }

            if (info == null)
            {
                property.ForceUpdatePropertyNameAndPath(index);
            }

            // Do NOT update the property here. Property updating may cause this property to be requested before
            // it has been registered, resulting in an infinite loop. It is the calling code's responsibility to
            // update the property before usage.

            return(property);
        }
Beispiel #6
0
        //internal void ForceUpdatePropertyNameAndPath(int? newIndex)
        //{
        //    if (newIndex != null)
        //    {
        //        this.Index = newIndex.Value;
        //    }

        //    this.unityPropertyPath = null;
        //    this.prefabModificationPath = null;

        //    if (this.Parent != null)
        //    {
        //        this.Path = this.Parent.Children.GetPath(this.Index);
        //    }
        //    else
        //    {
        //        this.Path = this.Info.PropertyName;
        //    }

        //    // Children may be null, as this may be called before the property has ever updated itself
        //    if (this.Children != null)
        //    {
        //        this.Children.ClearCaches();

        //        for (int i = 0; i < this.Children.Count; i++)
        //        {
        //            this.Children[i].ForceUpdatePropertyNameAndPath(null);
        //        }
        //    }
        //}

        internal static InspectorProperty Create(PropertyTree tree, InspectorProperty parent, InspectorPropertyInfo info, int index, bool isSecretRoot)
        {
            // Validate parameters first
            if (tree == null)
            {
                throw new ArgumentNullException("tree");
            }

            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            if (parent != null)
            {
                if (tree != parent.Tree)
                {
                    throw new ArgumentException("The given tree and the given parent's tree are not the same tree.");
                }

                if (index < 0 || index >= parent.Children.Count)
                {
                    throw new IndexOutOfRangeException("The given index for the property to create is out of bounds.");
                }
            }

            // Now start building a property
            InspectorProperty property = new InspectorProperty();

            // Set some basic values
            property.Tree    = tree;
            property.Info    = info;
            property.Parent  = parent;
            property.Index   = index;
            property.Context = new PropertyContextContainer(property);

            // Find property path
            {
                if (parent != null)
                {
                    property.Path = parent.Children.GetPath(index);
                }
                else
                {
                    property.Path = info.PropertyName;
                }

                if (property.Path == null)
                {
                    Debug.Log("Property path is null for property " + ObjectNames.NicifyVariableName(info.PropertyName.TrimStart('#', '$')) + "!");
                }
            }

            // Find parent value property
            if (parent != null)
            {
                InspectorProperty current = property;

                do
                {
                    current = current.Parent;
                }while (current != null && current.BaseValueEntry == null);

                property.ParentValueProperty = current;
            }

            // Set parent type and values
            if (property.ParentValueProperty != null)
            {
                property.ParentType   = property.ParentValueProperty.ValueEntry.TypeOfValue;
                property.ParentValues = new ImmutableList(property.ParentValueProperty.ValueEntry.WeakValues);
            }
            else
            {
                property.ParentType   = tree.TargetType;
                property.ParentValues = new ImmutableList(tree.WeakTargets);
            }

            // Find serializing/owning property
            {
                InspectorProperty current = property.ParentValueProperty;

                while (current != null && !current.ValueEntry.TypeOfValue.InheritsFrom(typeof(UnityEngine.Object)))
                {
                    current = current.ParentValueProperty;
                }

                if (current != null)
                {
                    property.SerializationRoot = current;
                }
                else
                {
                    property.SerializationRoot = isSecretRoot ? property : tree.SecretRootProperty;
                }
            }

            // Set name and label
            {
                property.Name = info.PropertyName;

                var mi = property.Info.GetMemberInfo() as MethodInfo;
                if (mi != null)
                {
                    var name        = property.Name;
                    var parensIndex = name.IndexOf('(');

                    if (parensIndex >= 0)
                    {
                        name = name.Substring(0, parensIndex);
                    }

                    property.NiceName = name.TrimStart('#', '$').SplitPascalCase();
                }
                else
                {
                    property.NiceName = ObjectNames.NicifyVariableName(property.Name.TrimStart('#', '$'));
                }

                property.Label = new GUIContent(property.NiceName);
            }

            // Create a value entry if necessary
            if (property.Info.PropertyType == PropertyType.Value)
            {
                property.BaseValueEntry = PropertyValueEntry.Create(property, info.TypeOfValue, isSecretRoot);
                property.ValueEntry     = property.BaseValueEntry;
            }

            // Do NOT update the property here. Property updating may cause this property to be requested before
            // it has been registered, resulting in an infinite loop. It is the calling code's responsibility to
            // update the property before usage.

            if (!isSecretRoot)
            {
                property.RefreshProcessedAttributes();
                property.ChildResolver = tree.PropertyResolverLocator.GetResolver(property);
                property.Children      = new PropertyChildren(property);
            }

            return(property);
        }
Beispiel #7
0
 public override bool CanResolveForPropertyFilter(InspectorProperty property)
 {
     return(property != property.Tree.SecretRootProperty);
 }
Beispiel #8
0
 public static InspectorPropertyInfo CreateForMember(InspectorProperty parentProperty, MemberInfo member, bool allowEditable, IEnumerable <Attribute> attributes)
 {
     return(CreateForMember(member, allowEditable, InspectorPropertyInfoUtility.GetSerializationBackend(parentProperty, member), attributes.ToList()));
 }
 /// <summary>
 /// Draws the property group with GUILayout support. This method is called from DrawPropertyImplementation if the GUICallType is set to GUILayout, which is the default.
 /// </summary>
 /// <param name="property">The property.</param>
 /// <param name="attribute">The attribute.</param>
 /// <param name="label">The label. This can be null, so make sure your drawer supports that.</param>
 protected virtual void DrawPropertyGroupLayout(InspectorProperty property, TGroupAttribute attribute, GUIContent label)
 {
     EditorGUILayout.LabelField(label, "The DrawPropertyGroupLayout method has not been implemented for the drawer of type '" + this.GetType().GetNiceName() + "'.");
 }
 /// <summary>
 /// Return the GUI height of the property. This method is called by DrawPropertyImplementation if the GUICallType is set to Rect, which is not the default.
 /// If the GUICallType is set to Rect, both GetRectHeight and DrawPropertyGroupRect needs to be implemented.
 /// If the GUICallType is set to GUILayout, implementing DrawPropertyGroupLayout will suffice.
 /// </summary>
 /// <param name="property">The property.</param>
 /// <param name="attribute">The attribute.</param>
 /// <param name="label">The label. This can be null, so make sure your drawer supports that.</param>
 /// <returns>Returns EditorGUIUtility.singleLineHeight by default.</returns>
 protected virtual float GetRectHeight(InspectorProperty property, TGroupAttribute attribute, GUIContent label)
 {
     return(EditorGUIUtility.singleLineHeight);
 }
 protected virtual bool CanDrawGroup(InspectorProperty property)
 {
     return(true);
 }
 public sealed override bool CanDrawProperty(InspectorProperty property)
 {
     return(property.Info.PropertyType == PropertyType.Group && this.CanDrawGroup(property));
 }
Beispiel #13
0
        /// <summary>
        /// Draws the proprety.
        /// </summary>
        protected override void DrawPropertyLayout(InspectorProperty property, TAttribute attribute, GUIContent label)
        {
            var entry = property.ValueEntry;

            if (SetAttribute == null || SetFieldInfo == null)
            {
                AllEditorGUI.ErrorMessageBox("Could not find the internal Unity fields 'PropertyDrawer.m_Attribute' or 'PropertyDrawer.m_FieldInfo'; UnityPropertyAttributeDrawer alias '" + typeof(UnityPropertyAttributeDrawer <TDrawer, TAttribute, TAttributeConstraint>).GetNiceName() + "' has been disabled.");
                return;
            }

            if (property.ValueEntry == null)
            {
                AllEditorGUI.ErrorMessageBox("Cannot put the attribute '" + typeof(TAttribute) + "' on a property of type '" + property.Info.PropertyType + "'.");
                return;
            }

            FieldInfo          fieldInfo;
            SerializedProperty unityProperty = property.Tree.GetUnityPropertyForPath(property.Path, out fieldInfo);

            if (unityProperty == null)
            {
                if (UnityVersion.IsVersionOrGreater(2017, 1))
                {
                    this.CallNextDrawer(entry, label);
                }
                else
                {
                    AllEditorGUI.ErrorMessageBox("Could not get a Unity SerializedProperty for the property '" + property.NiceName + "' of type '" + entry.TypeOfValue.GetNiceName() + "' at path '" + entry.Property.Path + "'.");
                }

                return;
            }

            SetFieldInfo(ref this.drawer, fieldInfo);
            SetAttribute(ref this.drawer, attribute);

            if (unityProperty.serializedObject.targetObject is EmittedScriptableObject)
            {
                var targetObjects = unityProperty.serializedObject.targetObjects;

                for (int i = 0; i < targetObjects.Length; i++)
                {
                    EmittedScriptableObject target = (EmittedScriptableObject)targetObjects[i];
                    target.SetWeakValue(entry.WeakValues[i]);
                }

                unityProperty.serializedObject.Update();
                unityProperty = unityProperty.serializedObject.FindProperty(unityProperty.propertyPath);
            }

            float height   = this.drawer.GetPropertyHeight(unityProperty, label);
            Rect  position = EditorGUILayout.GetControlRect(false, height);

            if (this.propertyHandler != null)
            {
                UnityPropertyHandlerUtility.PropertyHandlerOnGUI(this.propertyHandler, position, unityProperty, label, false);
            }
            else
            {
                this.drawer.OnGUI(position, unityProperty, label);
            }

            if (unityProperty.serializedObject.targetObject is EmittedScriptableObject)
            {
                unityProperty.serializedObject.ApplyModifiedPropertiesWithoutUndo();
                var targetObjects = unityProperty.serializedObject.targetObjects;

                for (int i = 0; i < targetObjects.Length; i++)
                {
                    EmittedScriptableObject target = (EmittedScriptableObject)targetObjects[i];
                    entry.WeakValues[i] = target.GetWeakValue();
                }
            }
        }