private void EditDeepType(TypeItem item, int deepLevel, Action <TypeItem> onChange)
 {
     if (item.type != null && item.type.IsGenericType)
     {
         var gType = item.type.GetGenericArguments();
         if (gType.Length > 0)
         {
             var filter = new FilterAttribute(item.filter);
             filter.Types.Clear();
             filter.OnlyGetType        = true;
             filter.UnityReference     = false;
             filter.DisplayRuntimeType = false;
             for (int i = 0; i < gType.Length; i++)
             {
                 var current = i;
                 EditType(gType[i], filter, deepLevel, (type) => {
                     if (type != null)
                     {
                         var typeDefinition = item.type.GetGenericTypeDefinition();
                         gType[current]     = type;
                         item.SetType(typeDefinition.MakeGenericType(gType));
                         onChange(item);
                     }
                 });
             }
         }
     }
 }
        private void EditType(TypeItem item, Action <TypeItem> onChange)
        {
            FilterAttribute f       = item.filter ?? filter;
            string          valName = item.DisplayName;

            EditorGUILayout.BeginVertical("Box");
            Rect rect = GUILayoutUtility.GetRect(new GUIContent(valName), "Button");

            if (GUI.Button(rect, new GUIContent(valName, valName)))
            {
                if (Event.current.button == 0)
                {
                    if (Event.current.shift || Event.current.control)
                    {
                        CommandWindow.CreateWindow(uNodeGUIUtility.GUIToScreenRect(rect), (items) => {
                            var member = CompletionEvaluator.CompletionsToMemberData(items);
                            if (member != null)
                            {
                                item.Value = member;
                                onChange(item);
                                return(true);
                            }
                            return(false);
                        }, new CompletionEvaluator.CompletionSetting()
                        {
                            validCompletionKind = CompletionKind.Type | CompletionKind.Namespace | CompletionKind.Keyword,
                        });
                    }
                    ItemSelector.ShowAsNew(targetObject, f, delegate(MemberData value) {
                        item.Value = value;
                        onChange(item);
                    }, true).ChangePosition(rect.ToScreenRect());
                }
                else
                {
                    var         type = item.type;
                    GenericMenu menu = new GenericMenu();
                    if (type.IsGenericType)
                    {
                        var args = type.GetGenericArguments();
                        foreach (var t in args)
                        {
                            menu.AddItem(new GUIContent($"To {t.PrettyName()}"), false, () => {
                                item.SetType(t);
                                contentRect = Rect.zero;
                                Repaint();
                            });
                        }
                    }
                    menu.AddItem(new GUIContent($"To List<{type.PrettyName()}>"), false, () => {
                        item.SetType(typeof(List <>).MakeGenericType(type));
                        contentRect = Rect.zero;
                        Repaint();
                    });
                    menu.AddItem(new GUIContent($"To HashSet<{type.PrettyName()}>"), false, () => {
                        item.SetType(typeof(HashSet <>).MakeGenericType(type));
                        contentRect = Rect.zero;
                        Repaint();
                    });
                    menu.AddItem(new GUIContent($"To Dictionary<{type.PrettyName()}, {typeof(object).PrettyName()}>"), false, () => {
                        item.SetType(typeof(Dictionary <,>).MakeGenericType(type, typeof(object)));
                        contentRect = Rect.zero;
                        Repaint();
                    });
                    menu.ShowAsContext();
                }
            }
            EditDeepType(item, 1, onChange);
            bool flag = f.CanManipulateArray();

            if (flag)
            {
                if (item.type != null && item.type is RuntimeType)
                {
                    flag = false;
                }
                else if (item.Value != null && item.Value.targetType == MemberData.TargetType.uNodeType)
                {
                    flag = false;
                }
            }
            if (flag)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Array");
                GUILayout.Space(50);
                if (GUILayout.Button(new GUIContent("-")))
                {
                    if (item.array > 0)
                    {
                        item.array--;
                    }
                    onChange(item);
                }
                if (GUILayout.Button(new GUIContent("+")))
                {
                    item.array++;
                    onChange(item);
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
        }
        void OnGUI()
        {
            HandleKeyboard();
            Rect cRect = EditorGUILayout.BeginVertical("Box");

            GUILayout.Label(new GUIContent("Type Builder"), EditorStyles.toolbarButton);
            if (contentRect.height > 350)
            {
                scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
            }
            currentEvent = Event.current;
            if (Value != null)
            {
                for (int i = 0; i < Value.Length; i++)
                {
                    if (Value[i] == null)
                    {
                        Value[i] = new TypeItem(typeof(object));
                    }
                    int current = i;
                    EditType(Value[i], (item) => {
                        Value[current] = item;
                        Repaint();
                    });
                }
            }
            if (canAddType)
            {
                EditorGUILayout.BeginHorizontal();
                GUILayout.Label("Types");
                GUILayout.Space(50);
                if (GUILayout.Button(new GUIContent("-")))
                {
                    ArrayUtility.RemoveAt(ref Value, Value.Length - 1);
                }
                if (GUILayout.Button(new GUIContent("+")))
                {
                    ArrayUtility.Add(ref Value, new TypeItem(typeof(object)));
                }
                EditorGUILayout.EndHorizontal();
            }
            if (GUILayout.Button(new GUIContent("Select")))
            {
                if (filter.Types == null || filter.Types.Count == 0 || filter.Types.Contains(typeof(object)) || Value.All(i => (filter.IsValidType(i.type))) ||
                    Value.All(i => (i.Value != null && filter.IsValidType(i.Value.Get <Type>()))))
                {
                    Close();
                    selectCallback(Value.Select(item => item.Value).ToArray());
                }
            }
            if (contentRect.height > 350)
            {
                GUI.EndScrollView();
            }
            EditorGUILayout.EndVertical();
            if (contentRect == Rect.zero && Event.current.type == EventType.Repaint)
            {
                contentRect = cRect;
                maxSize     = new Vector2(maxSize.x, contentRect.height + 10);
            }
            //GUILayout.FlexibleSpace();
        }