private bool VisitStructOrEnum <TContainer>(ref TContainer container, UTinyObject tiny, UTinyType type, int index) where TContainer : IPropertyContainer
        {
            var drawer = Mode == InspectMode.Normal && type.HasAttribute <EditorInspectorAttributes.CustomDrawerAttribute>() ?
                         type.GetAttribute <EditorInspectorAttributes.CustomDrawerAttribute>().Visitor :
                         s_DefaultStructVisitor;

            TransferState(drawer);
            var label = ConstructLabel(index >= 0 ? index.ToString() : tiny.Name);

            // We are in a list
            if (index >= 0)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.BeginVertical();
            }
            try
            {
                return(drawer.VisitStruct(tiny, label));
            }
            finally
            {
                if (index >= 0)
                {
                    EditorGUILayout.EndVertical();
                    if (GUILayout.Button("x", GUILayout.Width(16.0f), GUILayout.Height(16.0f)))
                    {
                        RemoveAtIndex = index;
                    }
                    EditorGUILayout.EndHorizontal();
                }
            }
        }
        public bool VisitTinyObject <TContainer>(ref TContainer container, UTinyObject tiny, UTinyType type, int index) where TContainer : IPropertyContainer
        {
            bool showProperties = true;

            // Root is [component|struct|enum], and recursive calls are [struct|enum]
            if (IsRoot)
            {
                GUILayout.Space(5);
                // Header
                showProperties = DoRootObject(tiny, type);
            }

            try
            {
                if (EditorGUILayout.BeginFadeGroup(showProperties ? 1.0f : 0.0f))
                {
                    GUI.enabled &= !type.HasAttribute <ReadonlyAttribute>();
                    var indent = EditorGUI.indentLevel;
                    EditorGUI.indentLevel = s_Depth - 1;

                    try
                    {
                        switch (type.TypeCode)
                        {
                        case UTinyTypeCode.Configuration:
                        case UTinyTypeCode.Component:
                            return(VisitComponent(tiny, type));

                        case UTinyTypeCode.Struct:
                        case UTinyTypeCode.Enum:
                            return(VisitStructOrEnum(ref container, tiny, type, index));

                        default:
                            return(false);
                        }
                    }
                    finally
                    {
                        EditorGUI.indentLevel = indent;
                        if (IsRoot && tiny.Properties.PropertyBag.PropertyCount > 0)
                        {
                            GUILayout.Space(5);
                        }
                        EditorGUILayout.EndFadeGroup();
                    }
                }
            }
            finally
            {
                if (IsRoot)
                {
                    UTinyGUILayout.Separator(UTinyColors.Inspector.Separator, UTinyGUIUtility.ComponentSeperatorHeight);
                }
            }
            return(true);
        }
 private bool VisitComponent(UTinyObject tiny, UTinyType type)
 {
     ++EditorGUI.indentLevel;
     try
     {
         var editor = Mode == InspectMode.Normal && type.HasAttribute <EditorInspectorAttributes.CustomComponentEditor>() ?
                      type.GetAttribute <EditorInspectorAttributes.CustomComponentEditor>().Visitor :
                      s_DefaultComponentVisitor;
         TransferState(editor);
         return(editor.VisitComponent(tiny));
     }
     finally
     {
         --EditorGUI.indentLevel;
     }
 }