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);
            }
        }
        public object OnSceneGUI(object element)
        {
            if (element != null)
            {
                PropertyEditorChain chain  = PropertyEditor.Get(element.GetType(), null);
                IPropertyEditor     editor = chain.SkipUntilNot(typeof(AbstractTypePropertyEditor));

                return(editor.OnSceneGUI(element));
            }
            return(element);
        }
        public float GetElementHeight(GUIContent label, object element, fiGraphMetadata metadata)
        {
            float height = EditorStyles.label.CalcHeight(label, 100);

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

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

            return(height);
        }
        public object Edit(Rect region, GUIContent label, object element, fiGraphMetadata metadata)
        {
            // draw the nullable type toggle
            {
                int labelHeight = (int)EditorStyles.label.CalcHeight(GUIContent.none, 100);

                Rect toggleRegion = new Rect(region);
                toggleRegion.height = labelHeight;
                region.y           += toggleRegion.height;
                region.height      -= toggleRegion.height;

                if (EditorGUI.Toggle(toggleRegion, label, element != null))
                {
                    if (element == null)
                    {
                        element     = _elementType.CreateInstance();
                        GUI.changed = true;
                    }
                }
                else
                {
                    element = null;
                }
            }

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

            // we have a value for the nullable type; draw the 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(NullablePropertyEditor));

                return(editor.Edit(selectedRegion, GUIContent.none, element, metadata.Enter("NullableEditor", metadata.Context)));
            }
        }
        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);
        }