Esempio n. 1
0
        void ImportUxmlFromProject(LibraryTreeItem projectCategory)
        {
            var filter = new SearchFilter();

            filter.searchArea = SearchFilter.SearchArea.AllAssets;
            filter.classNames = new string[] { "VisualTreeAsset" };
            var assets = AssetDatabase.FindAllAssets(filter);

            m_ProjectUxmlPathsHash = GetAllProjectUxmlFilePathsHash(assets);

            var categoryStack = new List <LibraryTreeItem>();

            foreach (var asset in assets)
            {
                var assetPath  = AssetDatabase.GetAssetPath(asset.instanceID);
                var prettyPath = assetPath;
                prettyPath = Path.GetDirectoryName(prettyPath);
                prettyPath = prettyPath.Replace('\\', '/');
                if (prettyPath.StartsWith(BuilderConstants.UIBuilderPackageRootPath))
                {
                    continue;
                }

                var split = prettyPath.Split('/');
                AddCategoriesToStack(projectCategory, categoryStack, split);

                var vta     = asset.pptrValue as VisualTreeAsset;
                var newItem = new LibraryTreeItem(asset.name + ".uxml",
                                                  () =>
                {
                    var tree = vta.CloneTree();
                    tree.SetProperty(BuilderConstants.LibraryItemLinkedTemplateContainerPathVEPropertyName, assetPath);
                    return(tree);
                },
                                                  (inVta, inParent) =>
                {
                    return(inVta.AddTemplateInstance(inParent, assetPath) as VisualElementAsset);
                });
                newItem.sourceAsset = vta;

                if (categoryStack.Count == 0)
                {
                    projectCategory.AddChild(newItem);
                }
                else
                {
                    categoryStack.Last().AddChild(newItem);
                }
            }
        }
Esempio n. 2
0
        static void AddCategoriesToStack(LibraryTreeItem sourceCategory, List <LibraryTreeItem> categoryStack, string[] split)
        {
            if (categoryStack.Count > split.Length)
            {
                categoryStack.RemoveRange(split.Length, categoryStack.Count - split.Length);
            }

            for (int i = 0; i < split.Length; ++i)
            {
                var part = split[i];

                if (categoryStack.Count > i)
                {
                    if (categoryStack[i].name == part)
                    {
                        continue;
                    }
                    else if (categoryStack[i].name != part)
                    {
                        categoryStack.RemoveRange(i, categoryStack.Count - i);
                    }
                }

                if (categoryStack.Count <= i)
                {
                    var newCategory = new LibraryTreeItem(part, () => null, null, new List <TreeViewItem <string> >());

                    if (categoryStack.Count == 0)
                    {
                        sourceCategory.AddChild(newCategory);
                    }
                    else
                    {
                        categoryStack[i - 1].AddChild(newCategory);
                    }

                    categoryStack.Add(newCategory);
                    continue;
                }
            }
        }
Esempio n. 3
0
        void RefreshTreeView()
        {
            Clear();
            LibraryTreeItem.ResetNextId();
            var items = new List <ITreeViewItem>();

            var unityItem = new LibraryTreeItem("Unity", () => null);

            unityItem.isHeader = true;
            IList <ITreeViewItem> unityItemList = new List <ITreeViewItem>()
            {
                new LibraryTreeItem("VisualElement",
                                    () =>
                {
                    var ve              = new VisualElement();
                    var veMinSizeChild  = new VisualElement();
                    veMinSizeChild.name = BuilderConstants.SpecialVisualElementInitialMinSizeName;
                    veMinSizeChild.AddToClassList(BuilderConstants.SpecialVisualElementInitialMinSizeClassName);
                    ve.Add(veMinSizeChild);
                    return(ve);
                },
                                    (inVta, inParent) =>
                {
                    var vea = new VisualElementAsset(typeof(VisualElement).ToString());
                    VisualTreeAssetUtilities.InitializeElement(vea);
                    inVta.AddElement(inParent, vea);
                    return(vea);
                }),
                new LibraryTreeItem("Button", () => new Button()
                {
                    text = "Button"
                }),
                new LibraryTreeItem("Scroller", () => new Scroller(0, 100, (v) => { }, SliderDirection.Horizontal)
                {
                    value = 42
                }),
                new LibraryTreeItem("Toggle", () => new Toggle("Toggle")),
                new LibraryTreeItem("Label", () => new Label("Label")),
                new LibraryTreeItem("Text Field", () => new TextField("Text Field")
                {
                    value = "filler text"
                }),
                new LibraryTreeItem("Object Field", () => new ObjectField("Object Field")
                {
                    value = new Texture2D(10, 10)
                    {
                        name = "new_texture"
                    }
                }),
                new LibraryTreeItem("Foldout", () => new Foldout()
                {
                    text = "Foldout"
                }),
                new LibraryTreeItem("Numeric Fields", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("Integer", () => new IntegerField("Int Field")
                    {
                        value = 42
                    }),
                    new LibraryTreeItem("Float", () => new FloatField("Float Field")
                    {
                        value = 42.2f
                    }),
                    new LibraryTreeItem("Long", () => new LongField("Long Field")
                    {
                        value = 42
                    }),
                    new LibraryTreeItem("Min-Max Slider", () => new MinMaxSlider("Min/Max Slider", 0, 20, -10, 40)
                    {
                        value = new Vector2(10, 12)
                    }),
                    new LibraryTreeItem("Slider", () => new Slider("Slider", 0, 100)
                    {
                        value = 42
                    }),
                    new LibraryTreeItem("Progress Bar", () => new ProgressBar()
                    {
                        title = "my-progress", value = 22
                    }),
                    new LibraryTreeItem("Vector2", () => new Vector2Field("Vec2 Field")),
                    new LibraryTreeItem("Vector3", () => new Vector3Field("Vec3 Field")),
                    new LibraryTreeItem("Vector4", () => new Vector4Field("Vec4 Field")),
                    new LibraryTreeItem("Rect", () => new RectField("Rect")),
                    new LibraryTreeItem("Bounds", () => new BoundsField("Bounds")),
                    new LibraryTreeItem("Slider (Int)", () => new SliderInt("SliderInt", 0, 100)
                    {
                        value = 42
                    }),
                    new LibraryTreeItem("Vector2 (Int)", () => new Vector2IntField("Vector2Int")),
                    new LibraryTreeItem("Vector3 (Int)", () => new Vector3IntField("Vector3Int")),
                    new LibraryTreeItem("Rect (Int)", () => new RectIntField("RectInt")),
                    new LibraryTreeItem("Bounds (Int)", () => new BoundsIntField("BoundsInt"))
                }),
                new LibraryTreeItem("Value Fields", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("Color", () => new ColorField("Color")
                    {
                        value = Color.cyan
                    }),
                    new LibraryTreeItem("Curve", () => new CurveField("Curve")
                    {
                        value = new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(5, 8), new Keyframe(10, 4) })
                    }),
                    new LibraryTreeItem("Gradient", () => new GradientField("Gradient")
                    {
                        value = new Gradient()
                        {
                            colorKeys = new GradientColorKey[]
                            {
                                new GradientColorKey(Color.red, 0),
                                new GradientColorKey(Color.blue, 10),
                                new GradientColorKey(Color.green, 20)
                            }
                        }
                    })
                }),
                new LibraryTreeItem("Choice Fields", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("Enum", () => new EnumField("Enum", TextAlignment.Center)),

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

                    new LibraryTreeItem("Tag", () => new TagField("Tag", "Player")),
                    new LibraryTreeItem("Mask", () => new MaskField("Mask")),
                    new LibraryTreeItem("Layer", () => new LayerField("Layer")),
                    new LibraryTreeItem("LayerMask", () => new LayerMaskField("LayerMask"))
                }),
                new LibraryTreeItem("Containers", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("ScrollView", () => new ScrollView()),
                    new LibraryTreeItem("ListView", () => new ListView()),
                    new LibraryTreeItem("IMGUIContainer", () => new IMGUIContainer()),
                }),
                new LibraryTreeItem("Toolbar", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("Toolbar", () => new Toolbar()),
                    new LibraryTreeItem("Toolbar Menu", () => new ToolbarMenu()),
                    new LibraryTreeItem("Toolbar Button", () => new ToolbarButton {
                        text = "Button"
                    }),
                    new LibraryTreeItem("Toolbar Spacer", () => new ToolbarSpacer()),
                    new LibraryTreeItem("Toolbar Toggle", () => new ToolbarToggle {
                        label = "Toggle"
                    }),
#if UNITY_2019_3_OR_NEWER
                    new LibraryTreeItem("Toolbar Breadcrumbs", () => new ToolbarBreadcrumbs()),
#endif
                    new LibraryTreeItem("Toolbar Search Field", () => new ToolbarSearchField()),
                    new LibraryTreeItem("Toolbar Popup Search Field", () => new ToolbarPopupSearchField()),
                }),
                new LibraryTreeItem("Inspectors", () => null, null, new List <TreeViewItem <string> >()
                {
                    new LibraryTreeItem("PropertyField", () => new PropertyField())
                }),
            };

            unityItem.AddChildren(unityItemList);
            items.Add(unityItem);

            // From Project
            var fromProjectCategory = new LibraryTreeItem("Project", () => null);

            fromProjectCategory.isHeader = true;
            items.Add(fromProjectCategory);
            ImportUxmlFromProject(fromProjectCategory);
            ImportFactoriesFromSource(fromProjectCategory);

            var treeView = new TreeView()
            {
                name = k_TreeViewName
            };

            treeView.AddToClassList(k_TreeViewClassName);
            Add(treeView);

            treeView.viewDataKey = "samples-tree";
            treeView.itemHeight  = 20;
            treeView.rootItems   = items;
            treeView.makeItem    = () => MakeItem(); // This is apparently more optimal than "= MakeItem;".
            treeView.bindItem    = (e, i) => BindItem(e, i);
#if UNITY_2020_1_OR_NEWER
            treeView.onItemsChosen += (s) => OnItemsChosen(s);
#else
            treeView.onItemChosen += (s) => OnItemChosen(s);
#endif
            treeView.Refresh();

            // Make sure the Hierarchy View gets focus when the pane gets focused.
            primaryFocusable = treeView.Q <ListView>();

            // Auto-expand all items on load.
            foreach (var item in treeView.rootItems)
            {
                treeView.ExpandItem(item.id);
            }
        }
Esempio n. 4
0
        void ImportFactoriesFromSource(LibraryTreeItem sourceCategory)
        {
            List <IUxmlFactory>     deferredFactories = new List <IUxmlFactory>();
            FactoryProcessingHelper processingData    = new FactoryProcessingHelper();

            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 <LibraryTreeItem>();

            foreach (var known in processingData.knownTypes.Values)
            {
                var split = known.uxmlNamespace.Split('.');

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

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

                AddCategoriesToStack(sourceCategory, categoryStack, split);

                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);

                var newItem = new LibraryTreeItem(
                    known.uxmlName, () => known.Create(asset, context));
                if (categoryStack.Count == 0)
                {
                    sourceCategory.AddChild(newItem);
                }
                else
                {
                    categoryStack.Last().AddChild(newItem);
                }
            }
        }