public static void ObjectField <T>(string title, T content, bool allowSceneObject, bool showRemoveButton, Action <T> onValueChanged, Func <bool> validate, params GUILayoutOption[] options)
            where T : Object
        {
            EditorGUI.BeginChangeCheck();
            EditorCustomGUI.BeginErrorCheck(validate);
            T value;

            if (showRemoveButton)
            {
                EditorGUILayout.BeginHorizontal();
                value = (T)EditorGUILayout.ObjectField(title, content, typeof(T), allowSceneObject, options);
                EditorCustomGUI.EndErrorCheck();
                if (GUILayout.Button("×", EditorCustomGUI.RemoveButtonStyle, GUILayout.Width(25), GUILayout.Height(EditorGUIUtility.singleLineHeight)))
                {
                    value = default;
                }
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                value = (T)EditorGUILayout.ObjectField(title, content, typeof(T), allowSceneObject, options);
                EditorCustomGUI.EndErrorCheck();
            }
            if (!EditorGUI.EndChangeCheck())
            {
                return;
            }
            onValueChanged.Invoke(value);
        }
        public static void TextField(string title, string text, Action <string> onValueChanged, Func <bool> validate)
        {
            EditorGUI.BeginChangeCheck();
            EditorCustomGUI.BeginErrorCheck(validate);
            var value = EditorGUILayout.TextField(title, text);

            EditorCustomGUI.EndErrorCheck();
            if (!EditorGUI.EndChangeCheck())
            {
                return;
            }
            onValueChanged.Invoke(value);
        }
        public static void BeginObjectFieldFoldGroup <T>(string title, ObjectFieldToggleParameter parameter, bool allowSceneObject, bool showRemoveButton, Action <T> onValueChanged, Func <bool> validate) where T : Object
        {
            var backgroundRect = GUILayoutUtility.GetRect(1f, 17f);

            var labelRect = backgroundRect;

            labelRect.xMin += 32f;
            labelRect.xMax -= 20f;

            var foldoutRect = backgroundRect;

            foldoutRect.y     += 1f;
            foldoutRect.width  = 13f;
            foldoutRect.height = 13f;

            backgroundRect.xMin   = 0f;
            backgroundRect.width += 4f;

            // Background
            EditorGUI.DrawRect(backgroundRect, Styles.HeaderBackgroundColor);

            var origFontStyle = EditorStyles.label.fontStyle;

            EditorStyles.label.fontStyle = FontStyle.Bold;
            EditorCustomGUI.ObjectField(labelRect, title, (T)parameter.Content, allowSceneObject, showRemoveButton, onValueChanged, validate);
            EditorStyles.label.fontStyle = origFontStyle;

            // foldout
            parameter.Fold = GUI.Toggle(foldoutRect, parameter.Fold, GUIContent.none, EditorStyles.foldout);

            // Handle events
            var e = Event.current;

            if (e.type == EventType.MouseDown)
            {
                if (labelRect.Contains(e.mousePosition))
                {
                    if (e.button == 0)
                    {
                        parameter.Fold = !parameter.Fold;
                    }

                    e.Use();
                }
            }

            EditorGUILayout.BeginVertical();
            ObjectFieldFoldGroupStack.Push(parameter);
        }
        public static void FolderPathField(string label, string text, string title, Action <string> onValueChanged, Func <bool> validate)
        {
            using (new EditorGUILayout.HorizontalScope())
            {
                EditorGUI.BeginChangeCheck();
                EditorCustomGUI.BeginErrorCheck(validate);
                var value = EditorGUILayout.TextField(label, text);
                EditorCustomGUI.EndErrorCheck();
                if (EditorGUI.EndChangeCheck())
                {
                    onValueChanged.Invoke(value);
                }

                if (GUILayout.Button("...", EditorStyles.miniButton, GUILayout.Width(30)))
                {
                    onValueChanged(FolderUtil.GetSaveFolderPath(title));
                }
            }
        }