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