private void DrawRuntimeObject(Rect position, RuntimeSerializedObject runtimeSerializedObject)
        {
            var prop           = runtimeSerializedObject.GetIterator();
            var height         = RuntimeEasyGUI.GetSinglePropertyHeight(prop, new GUIContent(prop.DisplayName));
            var headerPosition = new Rect(position.x, position.y, position.width, height);

            headerPosition.xMin += Space;
            prop.IsExpanded      = EditorGUI.Foldout(headerPosition, prop.IsExpanded, prop.DisplayName);
            RuntimeEasyGUI.PropertyField(headerPosition, prop, null);

            if (prop.IsExpanded)
            {
                var y = RuntimeEasyGUI.GetPropertyHeight(prop, null);
                EditorGUI.indentLevel++;
                while (prop.NextVisible(false))
                {
                    var mainPosition = new Rect(position.x, position.y + y, position.width, height);
                    mainPosition.xMin += Space;
                    height             = RuntimeEasyGUI.GetPropertyHeight(prop, new GUIContent(prop.DisplayName), prop.IsExpanded, null);
                    RuntimeEasyGUI.PropertyField(mainPosition, prop, new GUIContent(prop.DisplayName), prop.IsExpanded, null);
                    y += height;
                }
                EditorGUI.indentLevel--;
            }
        }
        private float GetRuntimeObjectHeight(RuntimeSerializedObject runtimeSerializedObject)
        {
            var height = 0f;
            var prop   = runtimeSerializedObject.GetIterator();

            height += RuntimeEasyGUI.GetSinglePropertyHeight(prop, new GUIContent(prop.DisplayName));
            if (prop.IsExpanded)
            {
                while (prop.NextVisible(false))
                {
                    height += RuntimeEasyGUI.GetPropertyHeight(prop, new GUIContent(prop.DisplayName), prop.IsExpanded, null);
                }
            }
            return(height);
        }
        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 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);
            }
        }