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.
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; }
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); } } }
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); } } } }
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; }
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); } }
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); } } }
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; } } } } }
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); }
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); }
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); }