static List <ITreeViewItem> GenerateControlsItemsTree()
        {
            var controlsTree   = new List <ITreeViewItem>();
            var containersItem = new BuilderLibraryTreeItem(BuilderConstants.LibraryContainersSectionHeaderName, null, null, null)
            {
                IsHeader = true
            };
            IList <ITreeViewItem> containersItemList = new List <ITreeViewItem>
            {
                new BuilderLibraryTreeItem("VisualElement", "VisualElement", typeof(VisualElement), () =>
                {
                    var ve              = new VisualElement();
                    var veMinSizeChild  = new VisualElement();
                    veMinSizeChild.name = BuilderConstants.SpecialVisualElementInitialMinSizeName;
                    veMinSizeChild.AddToClassList(BuilderConstants.SpecialVisualElementInitialMinSizeClassName);
                    ve.Add(veMinSizeChild);
                    return(ve);
                },
                                           (inVta, inParent, ve) =>
                {
                    var vea = new VisualElementAsset(typeof(VisualElement).ToString());
                    VisualTreeAssetUtilities.InitializeElement(vea);
                    inVta.AddElement(inParent, vea);
                    return(vea);
                }),
                new BuilderLibraryTreeItem("ScrollView", "ScrollView", typeof(ScrollView), () => new ScrollView()),
                new BuilderLibraryTreeItem("ListView", "ListView", typeof(ListView), () => new ListView()),
                new BuilderLibraryTreeItem("IMGUI Container", "VisualElement", typeof(IMGUIContainer), () => new IMGUIContainer()),
            };

            containersItem.AddChildren(containersItemList);
            controlsTree.Add(containersItem);

            var controlsItem = new BuilderLibraryTreeItem(BuilderConstants.LibraryControlsSectionHeaderName, null, null, null, null, new List <TreeViewItem <string> >
            {
                new BuilderLibraryTreeItem("Label", nameof(Label), typeof(Label), () => new Label("Label")),
                new BuilderLibraryTreeItem("Button", nameof(Button), typeof(Button), () => new Button {
                    text = "Button"
                }),
                new BuilderLibraryTreeItem("Toggle", nameof(Toggle), typeof(Toggle), () => new Toggle("Toggle")),
                new BuilderLibraryTreeItem("Scroller", nameof(Scroller), typeof(Scroller), () => new Scroller(0, 100, (v) => { }, SliderDirection.Horizontal)
                {
                    value = 42
                }),
                new BuilderLibraryTreeItem("Text Field", nameof(TextField), typeof(TextField), () => new TextField("Text Field")
                {
                    value = "filler text"
                }),
                new BuilderLibraryTreeItem("Foldout", nameof(Foldout), typeof(Foldout), () => new Foldout {
                    text = "Foldout"
                }),
                new BuilderLibraryTreeItem("Slider", nameof(Slider), typeof(Slider), () => new Slider("Slider", 0, 100)
                {
                    value = 42
                }),
                new BuilderLibraryTreeItem("Min-Max Slider", nameof(MinMaxSlider), typeof(MinMaxSlider), () => new MinMaxSlider("Min/Max Slider", 0, 20, -10, 40)
                {
                    value = new Vector2(10, 12)
                }),
            })
            {
                IsHeader = true
            };

            var numericFields = new BuilderLibraryTreeItem("Numeric Fields", null, null, null, null, new List <TreeViewItem <string> >
            {
                new BuilderLibraryTreeItem("Integer", nameof(IntegerField), typeof(IntegerField), () => new IntegerField("Int Field")
                {
                    value = 42
                }),
                new BuilderLibraryTreeItem("Float", nameof(FloatField), typeof(FloatField), () => new FloatField("Float Field")
                {
                    value = 42.2f
                }),
                new BuilderLibraryTreeItem("Long", nameof(LongField), typeof(LongField), () => new LongField("Long Field")
                {
                    value = 42
                }),
                new BuilderLibraryTreeItem("Min-Max Slider", nameof(MinMaxSlider), typeof(MinMaxSlider), () => new MinMaxSlider("Min/Max Slider", 0, 20, -10, 40)
                {
                    value = new Vector2(10, 12)
                }),
                new BuilderLibraryTreeItem("Slider", nameof(Slider), typeof(Slider), () => new Slider("Slider", 0, 100)
                {
                    value = 42
                }),
                new BuilderLibraryTreeItem("Progress Bar", nameof(ProgressBar), typeof(ProgressBar), () => new ProgressBar()
                {
                    title = "my-progress", value = 22
                }),
                new BuilderLibraryTreeItem("Vector2", nameof(Vector2Field), typeof(Vector2Field), () => new Vector2Field("Vec2 Field")),
                new BuilderLibraryTreeItem("Vector3", nameof(Vector3Field), typeof(Vector3Field), () => new Vector3Field("Vec3 Field")),
                new BuilderLibraryTreeItem("Vector4", nameof(Vector4Field), typeof(Vector4Field), () => new Vector4Field("Vec4 Field")),
                new BuilderLibraryTreeItem("Rect", nameof(RectField), typeof(RectField), () => new RectField("Rect")),
                new BuilderLibraryTreeItem("Bounds", nameof(BoundsField), typeof(BoundsField), () => new BoundsField("Bounds")),
                new BuilderLibraryTreeItem("Slider (Int)", nameof(SliderInt), typeof(SliderInt), () => new SliderInt("SliderInt", 0, 100)
                {
                    value = 42
                }),
                new BuilderLibraryTreeItem("Vector2 (Int)", nameof(Vector2IntField), typeof(Vector2IntField), () => new Vector2IntField("Vector2Int")),
                new BuilderLibraryTreeItem("Vector3 (Int)", nameof(Vector3IntField), typeof(Vector3IntField), () => new Vector3IntField("Vector3Int")),
                new BuilderLibraryTreeItem("Rect (Int)", nameof(RectIntField), typeof(RectIntField), () => new RectIntField("RectInt")),
                new BuilderLibraryTreeItem("Bounds (Int)", nameof(BoundsIntField), typeof(BoundsIntField), () => new BoundsIntField("BoundsInt")),
                new BuilderLibraryTreeItem("Object Field", nameof(ObjectField), typeof(ObjectField), () => new ObjectField("Object Field")
                {
                    value = new Texture2D(10, 10)
                    {
                        name = "new_texture"
                    }
                }),
            })
            {
                IsEditorOnly = true, IsHeader = true
            };

            var valueFields = new BuilderLibraryTreeItem("Value Fields", null, null, null, null, new List <TreeViewItem <string> >
            {
                new BuilderLibraryTreeItem("Color", nameof(ColorField), typeof(ColorField), () => new ColorField("Color")
                {
                    value = Color.cyan
                }),
                new BuilderLibraryTreeItem("Curve", nameof(CurveField), typeof(CurveField), () => new CurveField("Curve")
                {
                    value = new AnimationCurve(new Keyframe(0, 0), new Keyframe(5, 8), new Keyframe(10, 4))
                }),
                new BuilderLibraryTreeItem("Gradient", nameof(GradientField), typeof(GradientField), () => new GradientField("Gradient")
                {
                    value = new Gradient()
                    {
                        colorKeys = new[]
                        {
                            new GradientColorKey(Color.red, 0),
                            new GradientColorKey(Color.blue, 10),
                            new GradientColorKey(Color.green, 20)
                        }
                    }
                })
            })
            {
                IsEditorOnly = true, IsHeader = true
            };

            var choiceFields = new BuilderLibraryTreeItem("Choice Fields", null, null, null, null, new List <TreeViewItem <string> >
            {
                new BuilderLibraryTreeItem("Enum", nameof(EnumField), typeof(EnumField), () => new EnumField("Enum", TextAlignment.Center)),

                // No UXML support for PopupField.
                //new LibraryTreeItem("Popup", () => new PopupField<string>("Normal Field", choices, 0)),

                new BuilderLibraryTreeItem("Tag", nameof(TagField), typeof(TagField), () => new TagField("Tag", "Player")),
                new BuilderLibraryTreeItem("Mask", nameof(MaskField), typeof(MaskField), () => new MaskField("Mask")),
                new BuilderLibraryTreeItem("Layer", nameof(LayerField), typeof(LayerField), () => new LayerField("Layer")),
                new BuilderLibraryTreeItem("LayerMask", nameof(LayerMaskField), typeof(LayerMaskField), () => new LayerMaskField("LayerMask"))
            })
            {
                IsEditorOnly = true, IsHeader = true
            };

            var toolbar = new BuilderLibraryTreeItem("Toolbar", null, null, null, null, new List <TreeViewItem <string> >
            {
                new BuilderLibraryTreeItem("Toolbar", "ToolbarElement", typeof(Toolbar), () => new Toolbar()),
                new BuilderLibraryTreeItem("Toolbar Menu", "ToolbarElement", typeof(ToolbarMenu), () => new ToolbarMenu()),
                new BuilderLibraryTreeItem("Toolbar Button", "ToolbarElement", typeof(ToolbarButton), () => new ToolbarButton {
                    text = "Button"
                }),
                new BuilderLibraryTreeItem("Toolbar Spacer", "ToolbarElement", typeof(ToolbarSpacer), () => new ToolbarSpacer()),
                new BuilderLibraryTreeItem("Toolbar Toggle", "ToolbarElement", typeof(ToolbarToggle), () => new ToolbarToggle {
                    label = "Toggle"
                }),
#if UNITY_2019_3_OR_NEWER
                new BuilderLibraryTreeItem("Toolbar Breadcrumbs", "ToolbarElement", typeof(ToolbarBreadcrumbs), () => new ToolbarBreadcrumbs()),
#endif
                new BuilderLibraryTreeItem("Toolbar Search Field", "ToolbarElement", typeof(ToolbarSearchField), () => new ToolbarSearchField()),
                new BuilderLibraryTreeItem("Toolbar Popup Search Field", "ToolbarElement", typeof(ToolbarPopupSearchField), () => new ToolbarPopupSearchField()),
            })
            {
                IsEditorOnly = true, IsHeader = true
            };

            var inspectors = new BuilderLibraryTreeItem("Inspectors", null, null, null, null, new List <TreeViewItem <string> >
            {
                new BuilderLibraryTreeItem("PropertyField", nameof(PropertyField), typeof(PropertyField), () => new PropertyField())
            })
            {
                IsEditorOnly = true, IsHeader = true
            };

            controlsTree.Add(controlsItem);
            controlsTree.Add(numericFields);
            controlsTree.Add(valueFields);
            controlsTree.Add(choiceFields);
            controlsTree.Add(toolbar);
            controlsTree.Add(inspectors);

            return(controlsTree);
        }
        public void ImportFactoriesFromSource(BuilderLibraryTreeItem sourceCategory)
        {
            var deferredFactories      = new List <IUxmlFactory>();
            var processingData         = new FactoryProcessingHelper();
            var emptyNamespaceControls = new List <ITreeViewItem>();

            foreach (var factories in VisualElementFactoryRegistry.factories)
            {
                if (factories.Value.Count == 0)
                {
                    continue;
                }

                var factory = factories.Value[0];
                if (!ProcessFactory(factory, processingData))
                {
                    // Could not process the factory now, because it depends on a yet unprocessed factory.
                    // Defer its processing.
                    deferredFactories.Add(factory);
                }
            }

            List <IUxmlFactory> deferredFactoriesCopy;

            do
            {
                deferredFactoriesCopy = new List <IUxmlFactory>(deferredFactories);
                foreach (var factory in deferredFactoriesCopy)
                {
                    deferredFactories.Remove(factory);
                    if (!ProcessFactory(factory, processingData))
                    {
                        // Could not process the factory now, because it depends on a yet unprocessed factory.
                        // Defer its processing again.
                        deferredFactories.Add(factory);
                    }
                }
            }while (deferredFactoriesCopy.Count > deferredFactories.Count);

            if (deferredFactories.Count > 0)
            {
                Debug.Log("Some factories could not be processed because their base type is missing.");
            }

            var categoryStack = new List <BuilderLibraryTreeItem>();

            foreach (var known in processingData.knownTypes.Values)
            {
                var split = known.uxmlNamespace.Split('.');
                if (split.Length == 0)
                {
                    continue;
                }

                // Avoid adding our own internal factories (like Package Manager templates).
                if (!Unsupported.IsDeveloperMode() && split.Length > 0 && s_NameSpacesToAvoid.Contains(split[0]))
                {
                    continue;
                }

                // Avoid adding UI Builder's own types, even in internal mode.
                if (split.Length >= 3 && split[0] == "Unity" && split[1] == "UI" && split[2] == "Builder")
                {
                    continue;
                }

                var asset     = new VisualElementAsset(known.uxmlQualifiedName);
                var slots     = new Dictionary <string, VisualElement>();
                var overrides = new List <TemplateAsset.AttributeOverride>();
                var vta       = ScriptableObject.CreateInstance <VisualTreeAsset>();
                var context   = new CreationContext(slots, overrides, vta, null);

                Type elementType = null;
                var  factoryType = known.GetType();
                while (factoryType != null && elementType == null)
                {
                    if (factoryType.IsGenericType && factoryType.GetGenericTypeDefinition() == typeof(UxmlFactory <,>))
                    {
                        elementType = factoryType.GetGenericArguments()[0];
                    }
                    else
                    {
                        factoryType = factoryType.BaseType;
                    }
                }

                var newItem = new BuilderLibraryTreeItem(
                    known.uxmlName, "CustomCSharpElement", elementType, () => known.Create(asset, context));
                newItem.hasPreview = true;

                if (string.IsNullOrEmpty(split[0]))
                {
                    emptyNamespaceControls.Add(newItem);
                }
                else
                {
                    AddCategoriesToStack(sourceCategory, categoryStack, split);
                    if (categoryStack.Count == 0)
                    {
                        sourceCategory.AddChild(newItem);
                    }
                    else
                    {
                        categoryStack.Last().AddChild(newItem);
                    }
                }
            }

            sourceCategory.AddChildren(emptyNamespaceControls);
        }