Esempio n. 1
0
        public override SharedInstance <T, TSerializer> Edit(Rect region, GUIContent label, SharedInstance <T, TSerializer> element, fiGraphMetadata metadata)
        {
            TryEnsureScript();

            if (typeof(TActual).IsGenericType)
            {
                region = EditorGUI.PrefixLabel(region, label);


                float ButtonRectWidth = 23;
                Rect  buttonRect = region, objectRect = region;

                buttonRect.x     += buttonRect.width - ButtonRectWidth;
                buttonRect.width  = ButtonRectWidth;
                buttonRect.height = EditorGUIUtility.singleLineHeight;

                objectRect.width -= buttonRect.width;

                if (GUI.Button(buttonRect, new GUIContent("\u2261")))
                {
                    fiSharedInstanceSelectorWindow.Show(typeof(T), typeof(SharedInstance <T, TSerializer>),
                                                        instance => {
                        metadata.GetMetadata <SharedInstanceMetadata>().UpdatedInstance = fiOption.Just((SharedInstance <T, TSerializer>)instance);
                    });
                }

                fiEditorGUI.PushHierarchyMode(false);
                // Use the standard object property editor
                element = EditorChain.GetNextEditor(this).Edit(objectRect, GUIContent.none, element, metadata.Enter("ObjectReference"));
                fiEditorGUI.PopHierarchyMode();
            }
            else
            {
                if (element != null)
                {
                    fiEditorGUI.PushHierarchyMode(false);
                    element.Instance = PropertyEditor.Get(typeof(T), null).FirstEditor.Edit(region, new GUIContent("Instance"), element.Instance, new fiGraphMetadataChild {
                        Metadata = metadata
                    });
                    fiEditorGUI.PopHierarchyMode();
                }
            }

            var sharedInstanceMetadata = metadata.GetMetadata <SharedInstanceMetadata>();

            if (sharedInstanceMetadata.UpdatedInstance.HasValue)
            {
                element = sharedInstanceMetadata.UpdatedInstance.Value;
                sharedInstanceMetadata.UpdatedInstance = fiOption <SharedInstance <T, TSerializer> > .Empty;
                GUI.changed = true;
            }

            return(element);
        }
Esempio n. 2
0
 public static void AnimatedEnd(fiGraphMetadata metadata)
 {
     var anim = metadata.GetMetadata<fiAnimationMetadata>();
     if (anim.IsAnimating) {
         EndFadeGroup();
     }
 }
Esempio n. 3
0
        public override Type Edit(Rect region, GUIContent label, Type element, fiGraphMetadata metadata)
        {
            Rect labelRect, buttonRect = region;

            if (string.IsNullOrEmpty(label.text) == false)
            {
                fiRectUtility.SplitHorizontalPercentage(region, .3f, 2, out labelRect, out buttonRect);
                GUI.Label(labelRect, label);
            }

            string displayed = "<no type>";

            if (element != null)
            {
                displayed = element.CSharpName();
            }

            StateObject stateObj = metadata.GetMetadata <StateObject>();

            if (GUI.Button(buttonRect, displayed))
            {
                TypeSelectionPopupWindow.CreateSelectionWindow(element, type => stateObj.Type = fiOption.Just(type));
            }

            if (stateObj.Type.HasValue)
            {
                GUI.changed = true;
                var type = stateObj.Type.Value;
                stateObj.Type = fiOption <Type> .Empty;
                return(type);
            }

            return(element);
        }
Esempio n. 4
0
        public override float GetElementHeight(GUIContent label, UnityObject element, fiGraphMetadata metadata)
        {
            float height = FoldoutHeight;

            if (CanDisplayDropdown(element))
            {
                DisableFoldoutByDefault(element, metadata);

                var foldoutState = metadata.GetMetadata <ObjectFoldoutStateGraphMetadata>();
                if (foldoutState.IsActive || foldoutState.IsAnimating)
                {
                    var faded  = foldoutState.AnimPercentage;
                    var editor = BehaviorEditor.Get(element.GetType());

                    DynamicItemHeight.SetHeight(editor.GetHeight(element));

                    float itemHeight = DisplayedItemLayout.Height;
                    fiEditorGUI.UpdateFadeGroupHeight(ref itemHeight, 0, faded);
                    height += itemHeight;

                    DynamicItemHeight.SetHeight(0);
                }
            }

            return(height);
        }
Esempio n. 5
0
 public static void AnimatedBegin(ref Rect rect, fiGraphMetadata metadata)
 {
     var anim = metadata.GetMetadata<fiAnimationMetadata>();
     if (anim.IsAnimating) {
         BeginFadeGroupHeight(0, ref rect, anim.AnimationHeight);
     }
 }
Esempio n. 6
0
        public static void AnimatedEnd(fiGraphMetadata metadata)
        {
            var anim = metadata.GetMetadata <fiAnimationMetadata>();

            if (anim.IsAnimating)
            {
                EndFadeGroup();
            }
        }
Esempio n. 7
0
        public static void AnimatedBegin(ref Rect rect, fiGraphMetadata metadata)
        {
            var anim = metadata.GetMetadata <fiAnimationMetadata>();

            if (anim.IsAnimating)
            {
                BeginFadeGroupHeight(0, ref rect, anim.AnimationHeight);
            }
        }
        public object Edit(Rect region, GUIContent label, object element, fiGraphMetadata metadata)
        {
            metadata.Enter("AbstractTypeEditor").Metadata.GetPersistentMetadata <fiDropdownMetadata>().ForceDisable();

            try {
                fiEditorGUI.AnimatedBegin(ref region, metadata);

                _options.RemoveExtraneousOptions();


                // draw the popup
                {
                    int popupHeight = (int)EditorStyles.popup.CalcHeight(GUIContent.none, 100);

                    Rect popupRegion = new Rect(region);
                    popupRegion.height = popupHeight;
                    region.y          += popupRegion.height;
                    region.height     -= popupRegion.height;

                    int selectedIndex = _options.GetDisplayOptionIndex(element);
                    int updatedIndex  = EditorGUI.Popup(popupRegion, label, selectedIndex, _options.GetDisplayOptions());

                    if (selectedIndex != updatedIndex)
                    {
                        metadata.GetMetadata <AbstractTypeAnimationMetadata>().ChangedTypes = true;
                    }

                    element = _options.UpdateObjectInstance(element, selectedIndex, updatedIndex);
                }

                // no element; no editor
                if (element == null)
                {
                    return(null);
                }

                // draw the instance specific property editor
                {
                    Rect selectedRegion = new Rect(region);
                    selectedRegion = fiRectUtility.IndentedRect(selectedRegion);
                    region.y      += selectedRegion.height;
                    region.height -= selectedRegion.height;

                    // show custom editor
                    PropertyEditorChain chain  = PropertyEditor.Get(element.GetType(), null);
                    IPropertyEditor     editor = chain.SkipUntilNot(typeof(AbstractTypePropertyEditor));

                    return(editor.Edit(selectedRegion, GUIContent.none, element, metadata.Enter("AbstractTypeEditor")));
                }
            }
            finally {
                fiEditorGUI.AnimatedEnd(metadata);
            }
        }
        private tkControlEditor GetControlEditor(object element, fiGraphMetadata graphMetadata)
        {
            tkControlPropertyEditor.fiLayoutPropertyEditorMetadata metadata;
            if (graphMetadata.TryGetMetadata(out metadata) == false)
            {
                metadata        = graphMetadata.GetMetadata <tkControlPropertyEditor.fiLayoutPropertyEditorMetadata>();
                metadata.Layout = ((tkCustomEditor)element).GetEditor();
            }

            return(metadata.Layout);
        }
Esempio n. 10
0
        public static float AnimatedHeight(float currentHeight, bool updateHeight, fiGraphMetadata metadata)
        {
            var anim = metadata.GetMetadata<fiAnimationMetadata>();
            if (updateHeight) anim.UpdateHeight(currentHeight);

            if (anim.IsAnimating) {
                fiEditorUtility.RepaintAllEditors();
                return anim.AnimationHeight;
            }

            return currentHeight;
        }
        private PageMetadata GetPageMetadata(fiGraphMetadata graphMetadata)
        {
            PageMetadata metadata;

            if (graphMetadata.TryGetMetadata(out metadata) == false)
            {
                metadata = graphMetadata.GetMetadata <PageMetadata>();
                metadata.PageEndIndex = _pageMinimumCollectionLength;
            }

            return(metadata);
        }
        // see http://answers.unity3d.com/questions/436295/how-to-have-a-gradient-editor-in-an-editor-script.html
        // for the inspiration behind this approach

        private ItemMetadata GetMetadata(fiGraphMetadata graphMetadata)
        {
            var metadata = graphMetadata.GetMetadata <ItemMetadata>();

            if (metadata.Container == null)
            {
                metadata.Container          = MetadataObject.AddComponent <TContainer>();
                metadata.SerializedObject   = new SerializedObject(metadata.Container);
                metadata.SerializedProperty = metadata.SerializedObject.FindProperty("Item");
            }

            return(metadata);
        }
        public object Edit(Rect region, GUIContent label, object element, fiGraphMetadata metadata)
        {
            metadata.Enter("AbstractTypeEditor", metadata.Context).Metadata.GetPersistentMetadata<fiDropdownMetadata>().ForceDisable();

            try {
                fiEditorGUI.AnimatedBegin(ref region, metadata);

                _options.RemoveExtraneousOptions();

                // draw the popup
                {
                    int popupHeight = (int)EditorStyles.popup.CalcHeight(GUIContent.none, 100);

                    Rect popupRegion = new Rect(region);
                    popupRegion.height = popupHeight;
                    region.y += popupRegion.height;
                    region.height -= popupRegion.height;

                    int selectedIndex = _options.GetDisplayOptionIndex(element);
                    int updatedIndex = EditorGUI.Popup(popupRegion, label, selectedIndex, _options.GetDisplayOptions());

                    if (selectedIndex != updatedIndex) {
                        metadata.GetMetadata<AbstractTypeAnimationMetadata>().ChangedTypes = true;
                    }

                    element = _options.UpdateObjectInstance(element, selectedIndex, updatedIndex);
                }

                // no element; no editor
                if (element == null) {
                    return null;
                }

                // draw the instance specific property editor
                {
                    Rect selectedRegion = new Rect(region);
                    selectedRegion = fiRectUtility.IndentedRect(selectedRegion);
                    region.y += selectedRegion.height;
                    region.height -= selectedRegion.height;

                    // show custom editor
                    PropertyEditorChain chain = PropertyEditor.Get(element.GetType(), null);
                    IPropertyEditor editor = chain.SkipUntilNot(typeof(AbstractTypePropertyEditor));

                    return editor.Edit(selectedRegion, GUIContent.none, element, metadata.Enter("AbstractTypeEditor", metadata.Context));
                }
            }
            finally {
                fiEditorGUI.AnimatedEnd(metadata);
            }
        }
Esempio n. 14
0
        /// <summary>
        /// Draws the actual property editors.
        /// </summary>
        private object EditPropertiesButtons(GUIContent label, Rect region, object element, fiGraphMetadata metadata)
        {
            // If we have a label, then our properties block is indented and we should use hierarchy mode. Otherwise
            // we do not have a label so our properties block is *not* indented so we should *not* use hierarchy mode.
            //
            // HACK: We also check the nesting depth - if we're the top-level editor, then we want to enable hierarchy
            //       mode
            fiEditorGUI.PushHierarchyMode(_cycleEdit.Depth == 1 || string.IsNullOrEmpty(label.text) == false);

            var categories = _metadata.GetCategories(InspectedMemberFilters.InspectableMembers);

            if (categories.Count > 0)
            {
                var selectedCategoryMetadata = metadata.GetMetadata <SelectedCategoryMetadata>();

                Rect toolbarRect = region;
                toolbarRect.height = CategoryToolbarHeight;
                region.y          += CategoryToolbarHeight + fiLateBindings.EditorGUIUtility.standardVerticalSpacing;
                region.height     -= CategoryToolbarHeight + fiLateBindings.EditorGUIUtility.standardVerticalSpacing;

                int index = selectedCategoryMetadata.SelectedCategoryIndex;
                selectedCategoryMetadata.SelectedCategoryIndex = GUI.Toolbar(toolbarRect, index, categories.Keys.ToArray());

                foreach (var member in categories.Values.ElementAt(index))
                {
                    EditInspectedMember(ref region, element, member, metadata);
                }

                // Make sure we don't prune metadata
                foreach (var member in _metadata.GetMembers(InspectedMemberFilters.InspectableMembers))
                {
                    metadata.Enter(member.Name);
                }
            }

            else
            {
                var orderedMembers = _metadata.GetMembers(InspectedMemberFilters.InspectableMembers);
                for (int i = 0; i < orderedMembers.Count; ++i)
                {
                    EditInspectedMember(ref region, element, orderedMembers[i], metadata);
                }
            }

            fiEditorGUI.PopHierarchyMode();

            return(element);
        }
        private static void EnsureInitialState(tkDatabaseContext context, fiGraphMetadata metadata)
        {
            if (context.editedList == null)
            {
                context.editedList = (IList)InspectedType.Get(typeof(TDerived)).CreateInstance();
            }

            TryEnsureValidIndex(context);

            // Set the global metadata to the graph metadata, as the graph metadata is persistent
            // but users still may want to access the global metadata.
            fiGlobalMetadata.Set(context.editedList, metadata.GetMetadata <InspectorDatabaseEditorMetadata>());

            // Disable the dropdown
            metadata.GetPersistentMetadata <fiDropdownMetadata>().ForceDisable();
        }
Esempio n. 16
0
        public static float AnimatedHeight(float currentHeight, bool updateHeight, fiGraphMetadata metadata)
        {
            var anim = metadata.GetMetadata <fiAnimationMetadata>();

            if (updateHeight)
            {
                anim.UpdateHeight(currentHeight);
            }

            if (anim.IsAnimating)
            {
                fiEditorUtility.RepaintAllEditors();
                return(anim.AnimationHeight);
            }

            return(currentHeight);
        }
Esempio n. 17
0
        public override LayerMask Edit(Rect region, GUIContent label, LayerMask element, fiGraphMetadata metadata)
        {
            var container = metadata.GetMetadata <LayerMaskMetadata>();

            // note: we delay construction of the GameObject because when the metadata is
            //       deserialized, we don't want to construct a new GameObject in another thread
            if (container.Container == null)
            {
                var obj = (GameObject)EditorUtility.CreateGameObjectWithHideFlags(
                    "ProxyLayerMaskEditor", HideFlags.HideInHierarchy | HideFlags.DontSave);

                container.Container       = obj.AddComponent <LayerMaskContainer>();
                container.Container.Value = element;
            }

            return(DoField(container, region, label, element));
        }
        public float GetElementHeight(GUIContent label, object element, fiGraphMetadata metadata)
        {
            float height = EditorStyles.popup.CalcHeight(label, 100);

            height += fiRectUtility.IndentVertical;

            if (element != null)
            {
                PropertyEditorChain chain  = PropertyEditor.Get(element.GetType(), null);
                IPropertyEditor     editor = chain.SkipUntilNot(typeof(AbstractTypePropertyEditor));

                height += editor.GetElementHeight(GUIContent.none, element, metadata.Enter("AbstractTypeEditor"));
            }

            var abstractTypeMetadata = metadata.GetMetadata <AbstractTypeAnimationMetadata>();

            height = fiEditorGUI.AnimatedHeight(height, abstractTypeMetadata.ChangedTypes, metadata);
            abstractTypeMetadata.ChangedTypes = false;
            return(height);
        }
Esempio n. 19
0
        private ItemMetadata GetContainer(fiGraphMetadata metadata)
        {
            var container = metadata.GetMetadata <ItemMetadata>();

            // note: we delay construction of the GameObject because when the metadata is
            //       deserialized, we don't want to construct a new GameObject in another thread
            //       via the GradientContainer constructor
            if (container.Container == null)
            {
                // note: using HideFlags.HideAndDontSave includes HideFlags.NotEditable
                var obj = EditorUtility.CreateGameObjectWithHideFlags("Proxy editor for " + typeof(T).CSharpName(),
                                                                      HideFlags.HideInHierarchy | HideFlags.DontSave);

                container.Container = obj.AddComponent <TContainer>();

                container.SerializedObject   = new SerializedObject(container.Container);
                container.SerializedProperty = container.SerializedObject.FindProperty("Item");
            }

            return(container);
        }
Esempio n. 20
0
        public override UnityObject Edit(Rect region, GUIContent label, UnityObject element, fiGraphMetadata metadata)
        {
            if (CanDisplayDropdown(element) == false)
            {
                region.height = FoldoutHeight;
                return(fiEditorGUI.ObjectField(region, label, element, typeof(ObjectType), AllowSceneObjects(element)));
            }

            // We have to show a foldout.

            DisableFoldoutByDefault(element, metadata);

            // The rect for the foldout
            Rect foldoutRect = region;

            foldoutRect.height = FoldoutHeight;
            if (string.IsNullOrEmpty(label.text) == false)
            {
                foldoutRect.width = EditorGUIUtility.labelWidth;
            }
            else
            {
                foldoutRect.width = 15;
            }

            Rect objectRect = region;

            objectRect.x     += foldoutRect.width;
            objectRect.width -= foldoutRect.width;
            objectRect.height = FoldoutHeight;

            var  foldoutState  = metadata.GetMetadata <ObjectFoldoutStateGraphMetadata>();
            bool updatedActive = EditorGUI.Foldout(foldoutRect, foldoutState.IsActive, label, /*toggleOnLabelClick:*/ true);

            if (updatedActive != foldoutState.IsActive && foldoutState.IsAnimating == false)
            {
                foldoutState.IsActive = updatedActive;
            }

            element = fiEditorGUI.ObjectField(objectRect, GUIContent.none, element, typeof(ObjectType), AllowSceneObjects(element));

            if (element != null && (foldoutState.IsActive || foldoutState.IsAnimating))
            {
                Rect subRect = new Rect(region);
                subRect.y      += FoldoutHeight;
                subRect.height -= FoldoutHeight;

                fiEditorGUI.BeginFadeGroup(0, ref subRect, foldoutState.AnimPercentage);

                // Reuse the height calculation from GetHeight from the BehaviorEditor by
                // calculating the base height of the layout when the dynamic item does not
                // contribute.
                DynamicItemHeight.SetHeight(0);
                DynamicItemHeight.SetHeight(subRect.height - DisplayedItemLayout.Height);

                Rect boxRect      = DisplayedItemLayout.GetSectionRect("Box", subRect);
                Rect propertyRect = DisplayedItemLayout.GetSectionRect("Item", subRect);

                GUI.Box(boxRect, GUIContent.none);

                fiEditorGUI.PushHierarchyMode(false);

                var editor = BehaviorEditor.Get(element.GetType());
                editor.Edit(propertyRect, element);

                fiEditorGUI.PopHierarchyMode();

                fiEditorGUI.EndFadeGroup();

                if (foldoutState.IsAnimating)
                {
                    fiEditorUtility.RepaintAllEditors();
                }
            }

            return(element);
        }
Esempio n. 21
0
        /// <summary>
        /// Draws the actual property editors.
        /// </summary>
        private object EditPropertiesButtons(GUIContent label, Rect region, object element, fiGraphMetadata metadata) {
            // If we have a label, then our properties block is indented and we should use hierarchy mode. Otherwise
            // we do not have a label so our properties block is *not* indented so we should *not* use hierarchy mode.
            //
            // HACK: We also check the nesting depth - if we're the top-level editor, then we want to enable hierarchy
            //       mode
            fiEditorGUI.PushHierarchyMode(_cycleEdit.Depth == 1 || string.IsNullOrEmpty(label.text) == false);

            var categories = _metadata.GetCategories(InspectedMemberFilters.InspectableMembers);
            if (categories.Count > 0) {
                var selectedCategoryMetadata = metadata.GetMetadata<SelectedCategoryMetadata>();

                Rect toolbarRect = region;
                toolbarRect.height = CategoryToolbarHeight;
                region.y += CategoryToolbarHeight + EditorGUIUtility.standardVerticalSpacing;
                region.height -= CategoryToolbarHeight + EditorGUIUtility.standardVerticalSpacing;

                int index = selectedCategoryMetadata.SelectedCategoryIndex;
                selectedCategoryMetadata.SelectedCategoryIndex = GUI.Toolbar(toolbarRect, index, categories.Keys.ToArray());

                foreach (var member in categories.Values.ElementAt(index)) {
                    EditInspectedMember(ref region, element, member, metadata);
                }

                // Make sure we don't prune metadata
                foreach (var member in _metadata.GetMembers(InspectedMemberFilters.InspectableMembers)) {
                    metadata.Enter(member.Name);
                }
            }

            else {
                var orderedMembers = _metadata.GetMembers(InspectedMemberFilters.InspectableMembers);
                for (int i = 0; i < orderedMembers.Count; ++i) {
                    EditInspectedMember(ref region, element, orderedMembers[i], metadata);
                }
            }

            fiEditorGUI.PopHierarchyMode();

            return element;
        }
Esempio n. 22
0
        public float GetElementHeight(GUIContent label, object element, fiGraphMetadata metadata) {
            try {
                if (_cycleHeight == null) {
                    _cycleHeight = new fiCycleDetector(_cycleEdit, _cycleScene);
                }
                _cycleHeight.Enter();

                if (_cycleHeight.TryMark(element) == false) {
                    return EditorStyles.label.CalcHeight(GUIContent.none, 100);
                }

                float height = HasLabel(label) ? TitleHeight + fiRectUtility.IndentVertical : 0;

                if (element == null) {
                    // if the user want's an instance, we'll create one right away. We also check to
                    // make sure we should automatically instantiate references, as if we're pretty
                    // far down in the nesting level there may be an infinite recursion going on
                    if (fiSettings.InspectorAutomaticReferenceInstantation &&
                        _metadata.HasDefaultConstructor &&
                        ShouldAutoInstantiate()) {

                        element = _metadata.CreateInstance();
                        GUI.changed = true;
                    }

                    // otherwise we show a button to create an instance
                    else {
                        height += ButtonHeight;
                    }
                }

                if (element != null) {
                    // figure out which members we should display
                    List<InspectedMember> displayableMembers;
                    var categories = _metadata.GetCategories(InspectedMemberFilters.InspectableMembers);
                    if (categories.Count > 0) {
                        var selectedCategoryMetadata = metadata.GetMetadata<SelectedCategoryMetadata>();
                        height += CategoryToolbarHeight + EditorGUIUtility.standardVerticalSpacing;
                        displayableMembers = categories.Values.ElementAt(selectedCategoryMetadata.SelectedCategoryIndex);
                    }
                    else {
                        displayableMembers = _metadata.GetMembers(InspectedMemberFilters.InspectableMembers);
                    }

                    // compute the height of the members we will display
                    for (int i = 0; i < displayableMembers.Count; ++i) {
                        var member = displayableMembers[i];

                        // requested skip
                        if (ShouldShowMemberDynamic(element, member.MemberInfo) == false) {
                            continue;
                        }

                        var childMetadata = metadata.Enter(member.Name);

                        if (member.IsMethod) {
                            height += ButtonHeight;
                        }
                        else {
                            fiGraphMetadataCallbacks.PropertyMetadataCallback(childMetadata.Metadata, member.Property);
                            height += fiEditorGUI.EditPropertyHeight(element, member.Property, childMetadata);
                        }

                        height += DividerHeight;
                    }

                    // Remove the last divider
                    if (displayableMembers.Count > 0) height -= DividerHeight;
                }

                return height;
            }
            finally {
                _cycleHeight.Exit();
                if (_cycleHeight.Depth == 0) {
                    _cycleHeight = null;
                }
            }
        }
Esempio n. 23
0
        public float GetElementHeight(GUIContent label, object element, fiGraphMetadata metadata)
        {
            try {
                if (_cycleHeight == null)
                {
                    _cycleHeight = new fiCycleDetector(_cycleEdit, _cycleScene);
                }
                _cycleHeight.Enter();

                if (_cycleHeight.TryMark(element) == false)
                {
                    return(EditorStyles.label.CalcHeight(GUIContent.none, 100));
                }

                float height = HasLabel(label) ? TitleHeight + fiRectUtility.IndentVertical : 0;

                if (element == null)
                {
                    // if the user want's an instance, we'll create one right away. We also check to
                    // make sure we should automatically instantiate references, as if we're pretty
                    // far down in the nesting level there may be an infinite recursion going on
                    if (fiSettings.InspectorAutomaticReferenceInstantation &&
                        _metadata.HasDefaultConstructor &&
                        ShouldAutoInstantiate())
                    {
                        element     = _metadata.CreateInstance();
                        GUI.changed = true;
                    }

                    // otherwise we show a button to create an instance
                    else
                    {
                        height += ButtonHeight;
                    }
                }

                if (element != null)
                {
                    // figure out which members we should display
                    List <InspectedMember> displayableMembers;
                    var categories = _metadata.GetCategories(InspectedMemberFilters.InspectableMembers);
                    if (categories.Count > 0)
                    {
                        var selectedCategoryMetadata = metadata.GetMetadata <SelectedCategoryMetadata>();
                        height            += CategoryToolbarHeight + fiLateBindings.EditorGUIUtility.standardVerticalSpacing;
                        displayableMembers = categories.Values.ElementAt(selectedCategoryMetadata.SelectedCategoryIndex);
                    }
                    else
                    {
                        displayableMembers = _metadata.GetMembers(InspectedMemberFilters.InspectableMembers);
                    }

                    // compute the height of the members we will display
                    for (int i = 0; i < displayableMembers.Count; ++i)
                    {
                        var member = displayableMembers[i];

                        // requested skip
                        if (ShouldShowMemberDynamic(element, member.MemberInfo) == false)
                        {
                            continue;
                        }

                        var childMetadata = metadata.Enter(member.Name);

                        if (member.IsMethod)
                        {
                            height += ButtonHeight;
                        }
                        else
                        {
                            fiGraphMetadataCallbacks.PropertyMetadataCallback(childMetadata.Metadata, member.Property);
                            height += fiEditorGUI.EditPropertyHeight(element, member.Property, childMetadata);
                        }

                        height += DividerHeight;
                    }

                    // Remove the last divider
                    if (displayableMembers.Count > 0)
                    {
                        height -= DividerHeight;
                    }
                }

                return(height);
            }
            finally {
                _cycleHeight.Exit();
                if (_cycleHeight.Depth == 0)
                {
                    _cycleHeight = null;
                }
            }
        }
        public float GetElementHeight(GUIContent label, object element, fiGraphMetadata metadata)
        {
            float height = EditorStyles.popup.CalcHeight(label, 100);

            height += fiRectUtility.IndentVertical;

            if (element != null) {
                PropertyEditorChain chain = PropertyEditor.Get(element.GetType(), null);
                IPropertyEditor editor = chain.SkipUntilNot(typeof(AbstractTypePropertyEditor));

                height += editor.GetElementHeight(GUIContent.none, element, metadata.Enter("AbstractTypeEditor", metadata.Context));
            }

            var abstractTypeMetadata = metadata.GetMetadata<AbstractTypeAnimationMetadata>();
            height = fiEditorGUI.AnimatedHeight(height, abstractTypeMetadata.ChangedTypes, metadata);
            abstractTypeMetadata.ChangedTypes = false;
            return height;
        }