Base class to derive custom property drawers from. Use this to create custom drawers for your own Serializable classes or for script variables with custom PropertyAttributes.

상속: GUIDrawer
예제 #1
0
        public static PropertyDrawerDrawer Create(object value, UnityEditor.PropertyDrawer drawerInstance, Type drawerType, LinkedMemberInfo memberInfo, IParentDrawer parent, GUIContent label, bool setReadOnly)
        {
            if (memberInfo == null)
            {
                                #if DEV_MODE
                Debug.LogError("PropertyDrawerDrawer.Create(drawerType=" + drawerType.Name + ", parent=" + StringUtils.ToString(parent) + ", label=" + (label == null ? "null" : label.text) + "), returning null because fieldInfo was null");
                                #endif
                return(null);
            }

            if (memberInfo.SerializedProperty == null)
            {
                                #if DEV_MODE
                Debug.LogError("PropertyDrawerDrawer.Create(drawerType=" + drawerType.Name + ", parent=" + StringUtils.ToString(parent) + ", label=" + (label == null ? "null" : label.text) + "), returning null because fieldInfo.SerializedProperty was null");
                                #endif
                return(null);
            }

            PropertyDrawerDrawer result;
            if (!DrawerPool.TryGet(out result))
            {
                result = new PropertyDrawerDrawer();
            }
            result.Setup(value, drawerInstance, drawerType, memberInfo, parent, label, setReadOnly);
            result.LateSetup();
            return(result);
        }
 private void Init()
 {
     var dtp = ScriptAttributeUtility.GetDrawerTypeForType(_attrib.GetType());
     var drawer = PropertyDrawerActivator.Create(dtp, _attrib, _fieldInfo);
     if (drawer is PropertyModifier) (drawer as PropertyModifier).Init(true);
     _visibleDrawer = drawer;
 }
예제 #3
0
        public void HandleDrawnType(Type drawnType, Type propertyType, FieldInfo field, PropertyAttribute attribute)
        {
            Type drawerTypeForType = ScriptAttributeUtility.GetDrawerTypeForType(drawnType);

            if (drawerTypeForType != null)
            {
                if (typeof(PropertyDrawer).IsAssignableFrom(drawerTypeForType))
                {
                    if (propertyType != null && propertyType.IsArrayOrList())
                    {
                        return;
                    }
                    this.m_PropertyDrawer             = (PropertyDrawer)Activator.CreateInstance(drawerTypeForType);
                    this.m_PropertyDrawer.m_FieldInfo = field;
                    this.m_PropertyDrawer.m_Attribute = attribute;
                }
                else if (typeof(DecoratorDrawer).IsAssignableFrom(drawerTypeForType))
                {
                    if (field != null && field.FieldType.IsArrayOrList() && !propertyType.IsArrayOrList())
                    {
                        return;
                    }
                    DecoratorDrawer decoratorDrawer = (DecoratorDrawer)Activator.CreateInstance(drawerTypeForType);
                    decoratorDrawer.m_Attribute = attribute;
                    if (this.m_DecoratorDrawers == null)
                    {
                        this.m_DecoratorDrawers = new List <DecoratorDrawer>();
                    }
                    this.m_DecoratorDrawers.Add(decoratorDrawer);
                }
            }
        }
예제 #4
0
		public void HandleDrawnType(Type drawnType, Type propertyType, FieldInfo field, PropertyAttribute attribute)
		{
			Type drawerTypeForType = ScriptAttributeUtility.GetDrawerTypeForType(drawnType);
			if (drawerTypeForType != null)
			{
				if (typeof(PropertyDrawer).IsAssignableFrom(drawerTypeForType))
				{
					if (propertyType != null && propertyType.IsArrayOrList())
					{
						return;
					}
					this.m_PropertyDrawer = (PropertyDrawer)Activator.CreateInstance(drawerTypeForType);
					this.m_PropertyDrawer.m_FieldInfo = field;
					this.m_PropertyDrawer.m_Attribute = attribute;
				}
				else
				{
					if (typeof(DecoratorDrawer).IsAssignableFrom(drawerTypeForType))
					{
						if (field != null && field.FieldType.IsArrayOrList() && !propertyType.IsArrayOrList())
						{
							return;
						}
						DecoratorDrawer decoratorDrawer = (DecoratorDrawer)Activator.CreateInstance(drawerTypeForType);
						decoratorDrawer.m_Attribute = attribute;
						if (this.m_DecoratorDrawers == null)
						{
							this.m_DecoratorDrawers = new List<DecoratorDrawer>();
						}
						this.m_DecoratorDrawers.Add(decoratorDrawer);
					}
				}
			}
		}
예제 #5
0
        private void Setup(object setValue, [CanBeNull] UnityEditor.PropertyDrawer setDrawerInstance, [NotNull] Type drawerType, LinkedMemberInfo setMemberInfo, IParentDrawer setParent, GUIContent setLabel, bool setReadOnly)
        {
                        #if DEV_MODE && PI_ASSERTATIONS
            Debug.Assert(drawerType != null);
                        #endif

            if (setDrawerInstance == null)
            {
                setDrawerInstance = (UnityEditor.PropertyDrawer)drawerType.CreateInstance();
            }
            drawerInstance = setDrawerInstance;

                        #if DEV_MODE && PI_ASSERTATIONS
            Debug.Assert(drawerInstance != null, "Failed to create PropertyDrawer instance of type " + StringUtils.ToString(drawerType) + " for field of type " + StringUtils.ToString(DrawerUtility.GetType(setMemberInfo, setValue)) + " and attribute " + StringUtils.TypeToString(setMemberInfo == null ? null : setMemberInfo.GetAttribute <PropertyAttribute>()));
                        #endif

            memberInfo = setMemberInfo;

            var serializedProperty = SerializedProperty;
            if (serializedProperty != null)
            {
                // This is not fool-proof, because e.g. a custom property might use a foldout drawer
                // but could not figure out a better solution yet
                usesFoldout = serializedProperty.isArray;
            }
            else
            {
                usesFoldout = false;
            }

            var attField = drawerType.GetField("m_Attribute", BindingFlags.Instance | BindingFlags.NonPublic);

            if (setMemberInfo != null)
            {
                var atts = setMemberInfo.GetAttributes(Types.PropertyAttribute);
                if (atts.Length > 0)
                {
                    attField.SetValue(drawerInstance, atts[0]);
                }

                attField = drawerType.GetField("m_FieldInfo", BindingFlags.Instance | BindingFlags.NonPublic);
                attField.SetValue(drawerInstance, setMemberInfo.FieldInfo);
            }
            else
            {
                Debug.LogError("PropertyDrawerDrawer(\"" + (setLabel != null ? setLabel.text : "") + "\").Setup(" + drawerType.Name + ") - fieldInfo was null (parent=" + StringUtils.ToString(setParent) + ")");
            }

            base.Setup(setValue, DrawerUtility.GetType(setMemberInfo, setValue), setMemberInfo, setParent, setLabel, setReadOnly);
        }
        internal void Init(bool bIsVisibleDrawer)
        {
            if(_initialized) return;

            if(bIsVisibleDrawer)
            {
                var drawerTp = ScriptAttributeUtility.GetDrawerTypeForType(this.fieldInfo.FieldType);
                if (drawerTp != null)
                {
                    _subDrawer = PropertyDrawerActivator.Create(drawerTp, null, this.fieldInfo);
                }
            }

            _initialized = true;
        }
        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            var attributeType = ((PropertyFieldAttribute)attribute).attributeType;
            var arguments = ((PropertyFieldAttribute)attribute).arguments;

            if (attributeType == null)
                drawerOverride = GetPropertyDrawer(fieldInfo.FieldType, fieldInfo);
            else
                drawerOverride = GetPropertyAttributeDrawer(attributeType, fieldInfo, arguments);

            if (drawerOverride == null)
                return base.GetPropertyHeight(property, label);
            else
                return drawerOverride.GetPropertyHeight(property, label);
        }
        private void Init(SerializedProperty property)
        {
            _attributes = null;
            _modifiers = null;
            _visibleDrawer = null;

            _attributes = (from a in this.fieldInfo.GetCustomAttributes(typeof(PropertyAttribute), true) 
                           where !(a is ModifierChainAttribute) 
                           orderby (a as PropertyAttribute).order ascending 
                           select a as PropertyAttribute).ToArray();

            var propDrawerTp = typeof(PropertyDrawer);

            var lst = new List<PropertyModifier>();
            if (_attributes.Length > 0)
            {
                for (int i = 0; i < _attributes.Length - 1; i++)
                {
                    var attrib = _attributes[i];
                    if (attrib is PropertyModifierAttribute)
                    {
                        var dtp = ScriptAttributeUtility.GetDrawerTypeForType(attrib.GetType());
                        if(TypeUtil.IsType(dtp, typeof(PropertyModifier)))
                        {
                            var drawer = PropertyDrawerActivator.Create(dtp) as PropertyModifier;
                            if (drawer == null) continue;
                            PropertyDrawerActivator.InitializePropertyDrawer(drawer, attrib, this.fieldInfo);
                            drawer.Init(false);
                            lst.Add(drawer);
                        }
                    }
                }
                _modifiers = lst.ToArray();

                var lastAttrib = _attributes.Last();
                var lastDrawerTp = ScriptAttributeUtility.GetDrawerTypeForType(lastAttrib.GetType());
                if (TypeUtil.IsType(lastDrawerTp, typeof(PropertyDrawer)))
                {
                    var drawer = PropertyDrawerActivator.Create(lastDrawerTp, lastAttrib, this.fieldInfo);
                    if (drawer is PropertyModifier) (drawer as PropertyModifier).Init(true);
                    _visibleDrawer = drawer;
                }
            }

            _initialized = true;
        }
예제 #9
0
        private void Setup(object setValue, [CanBeNull] object attribute, [CanBeNull] UnityEditor.PropertyDrawer setDrawerInstance, [NotNull] Type drawerType, LinkedMemberInfo setMemberInfo, IParentDrawer setParent, GUIContent setLabel, bool setReadOnly)
        {
                        #if DEV_MODE && PI_ASSERTATIONS
            Debug.Assert(drawerType != null);
                        #endif

            if (setDrawerInstance == null)
            {
                setDrawerInstance = (UnityEditor.PropertyDrawer)drawerType.CreateInstance();
            }
            drawerInstance = setDrawerInstance;

                        #if DEV_MODE && PI_ASSERTATIONS
            Debug.Assert(drawerInstance != null, "Failed to create PropertyDrawer instance of type " + StringUtils.ToString(drawerType) + " for field of type " + StringUtils.ToString(DrawerUtility.GetType(setMemberInfo, setValue)) + " and attribute " + StringUtils.TypeToString(setMemberInfo == null ? null : setMemberInfo.GetAttribute <PropertyAttribute>()));
                        #endif

            memberInfo = setMemberInfo;

            var attField = drawerType.GetField("m_Attribute", BindingFlags.Instance | BindingFlags.NonPublic);

            if (setMemberInfo != null)
            {
                if (attribute != null)
                {
                                        #if DEV_MODE && DEBUG_ENABLED
                    Debug.Log("Setting field " + drawerType.Name + ".m_Attribute value to " + StringUtils.TypeToString(attribute));
                                        #endif

                    attField.SetValue(drawerInstance, attribute);
                }

                attField = drawerType.GetField("m_FieldInfo", BindingFlags.Instance | BindingFlags.NonPublic);
                attField.SetValue(drawerInstance, setMemberInfo.FieldInfo);
            }
            else
            {
                Debug.LogError("PropertyDrawerDrawer(\"" + (setLabel != null ? setLabel.text : "") + "\").Setup(" + drawerType.Name + ") - fieldInfo was null (parent=" + StringUtils.ToString(setParent) + ")");
            }

            base.Setup(setValue, DrawerUtility.GetType(setMemberInfo, setValue), setMemberInfo, setParent, setLabel, setReadOnly);

                        #if DEV_MODE && PI_ASSERTATIONS
            Debug.Assert(SerializedProperty != null, StringUtils.ToColorizedString(GetDevInfo()));
                        #endif
        }
        protected virtual void Init(PropertyAttribute[] attribs)
        {
            var fieldType = _fieldInfo.FieldType;
            if (fieldType.IsListType()) fieldType = fieldType.GetElementTypeOfListType();

            var fieldTypePropertyDrawerType = ScriptAttributeUtility.GetDrawerTypeForType(fieldType);
            if (fieldTypePropertyDrawerType != null && TypeUtil.IsType(fieldTypePropertyDrawerType, typeof(PropertyDrawer)))
            {
                _drawer = PropertyDrawerActivator.Create(fieldTypePropertyDrawerType, null, _fieldInfo);
                if (_drawer != null && _fieldInfo.FieldType.IsListType()) _drawer = new ArrayPropertyDrawer(_drawer);
            }


            foreach(var attrib in attribs)
            {
                this.HandleAttribute(attrib, _fieldInfo, fieldType);
            }
        }
예제 #11
0
        public bool CanCacheInspectorGUI(SerializedProperty property)
        {
            if (m_DecoratorDrawers != null &&
                !isCurrentlyNested &&
                m_DecoratorDrawers.Any(decorator => !decorator.CanCacheInspectorGUI()))
            {
                return(false);
            }

            if (propertyDrawer != null)
            {
                // Retrieve drawer BEFORE increasing nesting.
                PropertyDrawer drawer = propertyDrawer;
                using (var nestingContext = IncrementNestingContext())
                {
                    return(drawer.CanCacheInspectorGUISafe(property.Copy()));
                }
            }

            property = property.Copy();

            bool childrenAreExpanded = property.isExpanded && EditorGUI.HasVisibleChildFields(property);

            // Loop through all child properties
            if (childrenAreExpanded)
            {
                PropertyHandler    handler     = null;
                SerializedProperty endProperty = property.GetEndProperty();
                while (property.NextVisible(childrenAreExpanded) && !SerializedProperty.EqualContents(property, endProperty))
                {
                    if (handler == null)
                    {
                        handler = ScriptAttributeUtility.GetHandler(property);
                    }
                    if (!handler.CanCacheInspectorGUI(property))
                    {
                        return(false);
                    }
                    childrenAreExpanded = false;
                }
            }

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

            // If we found a drawer type, instantiate the drawer, cache it, and return it.
            if (drawerType != null)
            {
                if (typeof(PropertyDrawer).IsAssignableFrom(drawerType))
                {
                    // Use PropertyDrawer on array elements, not on array itself.
                    // If there's a PropertyAttribute on an array, we want to apply it to the individual array elements instead.
                    // This is the only convenient way we can let the user apply PropertyDrawer attributes to elements inside an array.
                    if (propertyType != null && propertyType.IsArrayOrList())
                    {
                        return;
                    }

                    m_PropertyDrawer             = (PropertyDrawer)System.Activator.CreateInstance(drawerType);
                    m_PropertyDrawer.m_FieldInfo = field;

                    // Will be null by design if default type drawer!
                    m_PropertyDrawer.m_Attribute = attribute;
                }
                else if (typeof(DecoratorDrawer).IsAssignableFrom(drawerType))
                {
                    // Draw decorators on array itself, not on each array elements
                    if (field != null && field.FieldType.IsArrayOrList() && !propertyType.IsArrayOrList())
                    {
                        return;
                    }

                    DecoratorDrawer decorator = (DecoratorDrawer)System.Activator.CreateInstance(drawerType);
                    decorator.m_Attribute = attribute;

                    if (m_DecoratorDrawers == null)
                    {
                        m_DecoratorDrawers = new List <DecoratorDrawer>();
                    }
                    m_DecoratorDrawers.Add(decorator);
                }
            }
        }
예제 #13
0
        public static PropertyDrawerDrawer Create(object value, object attribute, Type drawerType, LinkedMemberInfo memberInfo, IParentDrawer parent, GUIContent label, bool readOnly)
        {
            if (memberInfo == null)
            {
                                #if DEV_MODE
                Debug.LogError("PropertyDrawerDrawer.Create(drawerType=" + drawerType.Name + ", parent=" + StringUtils.ToString(parent) + ", label=" + (label == null ? "null" : label.text) + "), returning null because fieldInfo was null");
                                #endif
                return(null);
            }

            if (memberInfo.SerializedProperty == null)
            {
                                #if DEV_MODE
                Debug.LogError("PropertyDrawerDrawer.Create(drawerType=" + drawerType.Name + ", parent=" + StringUtils.ToString(parent) + ", label=" + (label == null ? "null" : label.text) + "), returning null because fieldInfo.SerializedProperty was null");
                                #endif
                return(null);
            }

            UnityEditor.PropertyDrawer drawerInstance;
            try
            {
                drawerInstance = drawerType.CreateInstance() as UnityEditor.PropertyDrawer;
            }
            catch (Exception e)
            {
                Debug.LogError("Failed to create instance of PropertyDrawer " + StringUtils.ToString(drawerType) + " " + e);
                return(null);
            }

            PropertyDrawerDrawer result;
            if (!DrawerPool.TryGet(out result))
            {
                result = new PropertyDrawerDrawer();
            }
            result.Setup(value, attribute, drawerInstance, drawerType, memberInfo, parent, label, readOnly);
            result.LateSetup();
            return(result);
        }
 public void HandleDrawnType(System.Type drawnType, System.Type propertyType, System.Reflection.FieldInfo field, PropertyAttribute attribute)
 {
   System.Type drawerTypeForType = ScriptAttributeUtility.GetDrawerTypeForType(drawnType);
   if (drawerTypeForType == null)
     return;
   if (typeof (PropertyDrawer).IsAssignableFrom(drawerTypeForType))
   {
     if (propertyType != null && propertyType.IsArrayOrList())
       return;
     this.m_PropertyDrawer = (PropertyDrawer) Activator.CreateInstance(drawerTypeForType);
     this.m_PropertyDrawer.m_FieldInfo = field;
     this.m_PropertyDrawer.m_Attribute = attribute;
   }
   else
   {
     if (!typeof (DecoratorDrawer).IsAssignableFrom(drawerTypeForType) || field != null && field.FieldType.IsArrayOrList() && !propertyType.IsArrayOrList())
       return;
     DecoratorDrawer instance = (DecoratorDrawer) Activator.CreateInstance(drawerTypeForType);
     instance.m_Attribute = attribute;
     if (this.m_DecoratorDrawers == null)
       this.m_DecoratorDrawers = new List<DecoratorDrawer>();
     this.m_DecoratorDrawers.Add(instance);
   }
 }
 protected override void HandleAttribute(PropertyAttribute attribute, System.Reflection.FieldInfo field, System.Type propertyType)
 {
     if(attribute is PropertyModifierAttribute)
     {
         var mtp = ScriptAttributeUtility.GetDrawerTypeForType(attribute.GetType());
         if (TypeUtil.IsType(mtp, typeof(PropertyModifier)))
         {
             var modifier = PropertyDrawerActivator.Create(mtp, attribute, field) as PropertyModifier;
             modifier.Init(false);
             if (_modifiers == null) _modifiers = new List<PropertyModifier>();
             _modifiers.Add(modifier);
         }
     }
     else
     {
         base.HandleAttribute(attribute, field, propertyType);
         var drawer = this.InternalDrawer;
         if (_drawer == null)
         {
             //no drawer has been set before... lets see if we got one
             if (drawer != null)
             {
                 //we got a new drawer, set it
                 if (field.FieldType.IsListType()) drawer = new ArrayPropertyDrawer(drawer);
                 _drawer = drawer;
             }
         }
         else if (drawer != _drawer)
         {
             //a new drawer was created, lets see what we need to do with it compared to the last one
             if (drawer is PropertyModifier)
             {
                 if (_modifiers == null) _modifiers = new List<PropertyModifier>();
                 _modifiers.Add(drawer as PropertyModifier);
                 this.InternalDrawer = _drawer;
             }
             else if (drawer is IArrayHandlingPropertyDrawer)
             {
                 //got an array drawer, this overrides previous drivers
                 if (_drawer is IArrayHandlingPropertyDrawer)
                 {
                     var temp = _drawer as IArrayHandlingPropertyDrawer;
                     _drawer = drawer;
                     (_drawer as IArrayHandlingPropertyDrawer).InternalDrawer = temp.InternalDrawer;
                 }
                 else if (_drawer != null)
                 {
                     var temp = _drawer;
                     _drawer = drawer;
                     (_drawer as IArrayHandlingPropertyDrawer).InternalDrawer = temp;
                 }
                 else
                 {
                     _drawer = drawer;
                 }
             }
             else if (_drawer is IArrayHandlingPropertyDrawer)
             {
                 //got an internal drawer for the existing array drawer
                 (_drawer as IArrayHandlingPropertyDrawer).InternalDrawer = drawer;
                 this.InternalDrawer = _drawer;
             }
             else
             {
                 //we got a new drawer, set it
                 if (field.FieldType.IsListType())
                 {
                     _drawer = new ArrayPropertyDrawer(drawer);
                     this.InternalDrawer = _drawer;
                 }
                 else
                 {
                     _drawer = drawer;
                 }
             }
         }
     }
 }
예제 #16
0
        void AddUnityVariableOfTypeToList(String name,Type type, ReorderableList list, PropertyDrawer drawer=null)
        {
            var index = list.serializedProperty.arraySize;
                        list.serializedProperty.arraySize++;
                        list.index = index;

                        UnityVariable variable = UnityVariable.CreateInstanceOf (type);
                                    variable.name = name;
                                    variable.drawer = drawer;

            //						UnityVariable variable = (UnityVariable)ScriptableObject.CreateInstance<UnityVariable> ();
            //						variable.name = name;
            //						variable.drawer = drawer;
            //						variable.Value = value;

                        var element = list.serializedProperty.GetArrayElementAtIndex (index);
                        element.objectReferenceValue = variable;

                        serializedObject.ApplyModifiedProperties ();
        }
 public ArrayPropertyDrawer(PropertyDrawer drawer)
 {
     _drawer = drawer;
 }
 protected void AppendDrawer(PropertyDrawer drawer)
 {
     if (_drawer == null)
     {
         //no drawer has been set before... lets see if we got one
         if(drawer is PropertyModifier)
         {
             if (_modifiers == null) _modifiers = new List<PropertyModifier>();
             _modifiers.Add(drawer as PropertyModifier);
             
             if(this.Field.FieldType.IsListType())
             {
                 _drawer = new ArrayPropertyDrawer(null);
                 this.InternalDrawer = _drawer;
             }
         }
         else if(drawer != null)
         {
             //we got a new drawer, set it
             if (this.Field.FieldType.IsListType()) drawer = new ArrayPropertyDrawer(drawer);
             _drawer = drawer;
         }
     }
     else if (drawer != _drawer)
     {
         //a new drawer was created, lets see what we need to do with it compared to the last one
         if (drawer is PropertyModifier)
         {
             if (_modifiers == null) _modifiers = new List<PropertyModifier>();
             _modifiers.Add(drawer as PropertyModifier);
             this.InternalDrawer = _drawer;
         }
         else if (drawer is IArrayHandlingPropertyDrawer)
         {
             //got an array drawer, this overrides previous drawers
             if (_drawer is IArrayHandlingPropertyDrawer)
             {
                 var temp = _drawer as IArrayHandlingPropertyDrawer;
                 _drawer = drawer;
                 (_drawer as IArrayHandlingPropertyDrawer).InternalDrawer = temp.InternalDrawer;
             }
             else if (_drawer != null)
             {
                 var temp = _drawer;
                 _drawer = drawer;
                 (_drawer as IArrayHandlingPropertyDrawer).InternalDrawer = temp;
             }
             else
             {
                 _drawer = drawer;
             }
         }
         else if (_drawer is IArrayHandlingPropertyDrawer)
         {
             //got an internal drawer for the existing array drawer
             (_drawer as IArrayHandlingPropertyDrawer).InternalDrawer = drawer;
             this.InternalDrawer = _drawer;
         }
         else
         {
             //we got a new drawer, set it
             if (this.Field.FieldType.IsListType())
             {
                 _drawer = new ArrayPropertyDrawer(drawer);
                 this.InternalDrawer = _drawer;
             }
             else
             {
                 _drawer = drawer;
             }
         }
     }
 }
 public static void InitializePropertyDrawer(PropertyDrawer drawer, PropertyAttribute attrib, System.Reflection.FieldInfo fieldInfo)
 {
     if (drawer == null) throw new System.ArgumentNullException("drawer");
     ObjUtil.SetValue(drawer, "m_Attribute", attrib);
     ObjUtil.SetValue(drawer, "m_FieldInfo", fieldInfo);
 }
예제 #20
0
        public float GetHeight(SerializedProperty property, GUIContent label, bool includeChildren)
        {
            float height = 0;

            if (m_DecoratorDrawers != null && !isCurrentlyNested)
            {
                foreach (DecoratorDrawer drawer in m_DecoratorDrawers)
                {
                    height += drawer.GetHeight();
                }
            }


            if (propertyDrawer != null)
            {
                // Retrieve drawer BEFORE increasing nesting.
                PropertyDrawer drawer = propertyDrawer;
                using (var nestingContext = IncrementNestingContext())
                {
                    height += drawer.GetPropertyHeightSafe(property.Copy(), label ?? EditorGUIUtility.TempContent(property.localizedDisplayName, tooltip));
                }
            }
            else if (!includeChildren)
            {
                height += EditorGUI.GetSinglePropertyHeight(property, label);
            }
            else if (UseReorderabelListControl(property))
            {
                ReorderableListWrapper reorderableList;
                string key = ReorderableListWrapper.GetPropertyIdentifier(property);

                // If collection doesn't have a ReorderableList assigned to it, create one and assign it
                if (!s_reorderableLists.TryGetValue(key, out reorderableList))
                {
                    reorderableList         = new ReorderableListWrapper(property, label, true);
                    s_reorderableLists[key] = reorderableList;
                }

                reorderableList.Property = property;
                height += s_reorderableLists[key].GetHeight();
                return(height);
            }
            else
            {
                property = property.Copy();

                // First property with custom label
                height += EditorGUI.GetSinglePropertyHeight(property, label);
                bool childrenAreExpanded = property.isExpanded && EditorGUI.HasVisibleChildFields(property);

                // Loop through all child properties
                var tc = EditorGUIUtility.TempContent(property.localizedDisplayName, tooltip);
                if (childrenAreExpanded)
                {
                    SerializedProperty endProperty = property.GetEndProperty();
                    while (property.NextVisible(childrenAreExpanded) && !SerializedProperty.EqualContents(property, endProperty))
                    {
                        height += ScriptAttributeUtility.GetHandler(property).GetHeight(property, tc, true);
                        childrenAreExpanded = false;
                        height += EditorGUI.kControlVerticalSpacing;
                    }
                }
            }

            return(height);
        }
예제 #21
0
        internal bool OnGUI(Rect position, SerializedProperty property, GUIContent label, bool includeChildren, Rect visibleArea)
        {
            TestInvalidateCache();

            float oldLabelWidth, oldFieldWidth;

            float propHeight = position.height;

            position.height = 0;
            if (m_DecoratorDrawers != null && !isCurrentlyNested)
            {
                foreach (DecoratorDrawer decorator in m_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 (propertyDrawer != null)
            {
                // Remember widths
                oldLabelWidth = EditorGUIUtility.labelWidth;
                oldFieldWidth = EditorGUIUtility.fieldWidth;
                // Draw with custom drawer - retrieve it BEFORE increasing nesting.
                PropertyDrawer drawer = propertyDrawer;

                using (var nestingContext = IncrementNestingContext())
                {
                    drawer.OnGUISafe(position, property.Copy(), label ?? EditorGUIUtility.TempContent(property.localizedDisplayName, tooltip));
                }

                // Restore widths
                EditorGUIUtility.labelWidth = oldLabelWidth;
                EditorGUIUtility.fieldWidth = oldFieldWidth;

                return(false);
            }
            else
            {
                if (!includeChildren)
                {
                    return(EditorGUI.DefaultPropertyField(position, property, label));
                }

                if (UseReorderabelListControl(property))
                {
                    ReorderableListWrapper reorderableList;
                    string key = ReorderableListWrapper.GetPropertyIdentifier(property);

                    if (!s_reorderableLists.TryGetValue(key, out reorderableList))
                    {
                        // Manual layout controls don't call GetHeight() method so we need to have a way to initialized list as we prepare to render it here
                        reorderableList         = new ReorderableListWrapper(property, label, true);
                        s_reorderableLists[key] = reorderableList;
                    }

                    // Calculate visibility rect specifically for reorderable list as when applied for the whole serialized object,
                    // it causes collapsed out of sight array elements appear thus messing up scroll-bar experience
                    var screenPos = GUIUtility.GUIToScreenPoint(position.position);

                    screenPos.y = Mathf.Clamp(screenPos.y,
                                              GUIView.current?.screenPosition.yMin ?? 0,
                                              GUIView.current?.screenPosition.yMax ?? Screen.height);

                    Rect listVisibility = new Rect(screenPos.x, screenPos.y,
                                                   GUIView.current?.screenPosition.width ?? Screen.width,
                                                   GUIView.current?.screenPosition.height ?? Screen.height);

                    listVisibility = GUIUtility.ScreenToGUIRect(listVisibility);

                    reorderableList.Property = property;
                    reorderableList.Draw(label, position, listVisibility, tooltip, includeChildren);
                    return(!includeChildren && property.isExpanded);
                }

                // Remember state
                Vector2 oldIconSize = EditorGUIUtility.GetIconSize();
                bool    wasEnabled  = GUI.enabled;
                int     origIndent  = EditorGUI.indentLevel;

                int relIndent = origIndent - property.depth;

                SerializedProperty prop = property.Copy();

                position.height = EditorGUI.GetSinglePropertyHeight(prop, label);

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

                // Loop through all child properties
                if (childrenAreExpanded)
                {
                    SerializedProperty endProperty = prop.GetEndProperty();
                    while (prop.NextVisible(childrenAreExpanded) && !SerializedProperty.EqualContents(prop, endProperty))
                    {
                        var handler = ScriptAttributeUtility.GetHandler(prop);
                        EditorGUI.indentLevel = prop.depth + relIndent;
                        position.height       = handler.GetHeight(prop, null, UseReorderabelListControl(prop) && includeChildren);

                        if (position.Overlaps(visibleArea))
                        {
                            EditorGUI.BeginChangeCheck();
                            childrenAreExpanded = handler.OnGUI(position, prop, null, UseReorderabelListControl(prop)) && EditorGUI.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 + EditorGUI.kControlVerticalSpacing;
                    }
                }

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

                return(false);
            }
        }
	public static bool IsEnabled(PropertyDrawer drawer, SerializedProperty property) {

		return PropertyExtensions.IsEnabled<ReadOnlyAttribute>(drawer, property);

	}