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