static void GenerateProjectContentTrees() { ProjectContentTree = new List <ITreeViewItem>(); ProjectContentTreeNoPackages = new List <ITreeViewItem>(); var fromProjectCategory = new BuilderLibraryTreeItem(BuilderConstants.LibraryAssetsSectionHeaderName, null, null, null) { IsHeader = true }; s_ProjectAssetsScanner.ImportUxmlFromProject(fromProjectCategory, true); ProjectContentTree.Add(fromProjectCategory); var fromProjectCategoryNoPackages = new BuilderLibraryTreeItem(BuilderConstants.LibraryAssetsSectionHeaderName, null, null, null) { IsHeader = true }; s_ProjectAssetsScanner.ImportUxmlFromProject(fromProjectCategoryNoPackages, false); ProjectContentTreeNoPackages.Add(fromProjectCategoryNoPackages); var customControlsCategory = new BuilderLibraryTreeItem(BuilderConstants.LibraryCustomControlsSectionHeaderName, null, null, null) { IsHeader = true }; s_ProjectAssetsScanner.ImportFactoriesFromSource(customControlsCategory); if (customControlsCategory.hasChildren) { ProjectContentTree.Add(customControlsCategory); ProjectContentTreeNoPackages.Add(customControlsCategory); } }
protected override bool StartDrag(VisualElement target, Vector2 mousePosition, VisualElement pill) { m_LibraryItem = target.GetProperty(BuilderConstants.LibraryItemLinkedManipulatorVEPropertyName) as BuilderLibraryTreeItem; if (m_LibraryItem == null) { return(false); } var isCurrentDocumentVisualTreeAsset = m_LibraryItem.sourceAsset == paneWindow.document.visualTreeAsset; if (isCurrentDocumentVisualTreeAsset) { return(false); } m_MadeElement = m_LibraryItem.makeVisualElementCallback?.Invoke(); if (m_MadeElement == null) { return(false); } m_TooltipPreview.Disable(); return(true); }
public void ImportUxmlFromProject(BuilderLibraryTreeItem projectCategory, bool includePackages) { var assets = AssetDatabase.FindAllAssets(m_SearchFilter); var categoryStack = new List <BuilderLibraryTreeItem>(); foreach (var asset in assets) { var assetPath = AssetDatabase.GetAssetPath(asset.instanceID); var prettyPath = assetPath; prettyPath = Path.GetDirectoryName(prettyPath); prettyPath = prettyPath.ConvertSeparatorsToUnity(); if (prettyPath.StartsWith("Packages/") && !includePackages) { continue; } if (prettyPath.StartsWith(BuilderConstants.UIBuilderPackageRootPath)) { continue; } var split = prettyPath.Split('/'); AddCategoriesToStack(projectCategory, categoryStack, split); var vta = asset.pptrValue as VisualTreeAsset; var newItem = new BuilderLibraryTreeItem(asset.name + ".uxml", null, typeof(TemplateContainer), () => { if (vta == null) { return(null); } var tree = vta.CloneTree(); tree.SetProperty(BuilderConstants.LibraryItemLinkedTemplateContainerPathVEPropertyName, assetPath); tree.name = vta.name; return(tree); }, (inVta, inParent, ve) => { var vea = inVta.AddTemplateInstance(inParent, assetPath) as VisualElementAsset; vea.AddProperty("name", vta.name); ve.SetProperty(BuilderConstants.ElementLinkedInstancedVisualTreeAssetVEPropertyName, vta); return(vea); }, null, vta); newItem.SetIcon((Texture2D)EditorGUIUtility.IconContent("UxmlScript Icon").image); newItem.HasPreview = true; if (categoryStack.Count == 0) { projectCategory.AddChild(newItem); } else { categoryStack.Last().AddChild(newItem); } } }
protected void AddItemToTheDocument(BuilderLibraryTreeItem item) { // If this is the uxml file entry of the currently open file, don't allow // the user to instantiate it (infinite recursion) or re-open it. var listOfOpenDocuments = m_PaneWindow.document.openUXMLFiles; bool isCurrentDocumentOpen = listOfOpenDocuments.Any(doc => doc.uxmlFileName == item.name); if (isCurrentDocumentOpen) { return; } if (m_PaneWindow.document.WillCauseCircularDependency(item.sourceAsset)) { BuilderDialogsUtility.DisplayDialog(BuilderConstants.InvalidWouldCauseCircularDependencyMessage, BuilderConstants.InvalidWouldCauseCircularDependencyMessageDescription, null); return; } var newElement = item.makeVisualElementCallback?.Invoke(); if (newElement == null) { return; } if (item.makeElementAssetCallback != null && newElement is TemplateContainer tempContainer) { if (!BuilderAssetUtilities.ValidateAsset(item.sourceAsset, item.sourceAssetPath)) { return; } } var activeVTARootElement = m_DocumentRootElement.Query().Where(e => e.GetVisualTreeAsset() == m_PaneWindow.document.visualTreeAsset).First(); if (activeVTARootElement == null) { Debug.LogError("UI Builder has a bug. Could not find document root element for currently active open UXML document."); return; } activeVTARootElement.Add(newElement); if (item.makeElementAssetCallback == null) { BuilderAssetUtilities.AddElementToAsset(m_PaneWindow.document, newElement); } else { BuilderAssetUtilities.AddElementToAsset( m_PaneWindow.document, newElement, item.makeElementAssetCallback); } m_Selection.NotifyOfHierarchyChange(); m_Selection.Select(null, newElement); }
internal static TreeViewItemData <BuilderLibraryTreeItem> CreateItem(string name, string iconName, Type type, Func <VisualElement> makeVisualElementCallback, Func <VisualTreeAsset, VisualElementAsset, VisualElement, VisualElementAsset> makeElementAssetCallback = null, List <TreeViewItemData <BuilderLibraryTreeItem> > children = null, VisualTreeAsset asset = null, int id = default, bool isHeader = false, bool isEditorOnly = false) { var itemId = BuilderLibraryTreeItem.GetItemId(name, type, asset, id); var data = new BuilderLibraryTreeItem(name, iconName, type, makeVisualElementCallback, makeElementAssetCallback, asset) { isHeader = isHeader, isEditorOnly = isEditorOnly }; return(new TreeViewItemData <BuilderLibraryTreeItem>(itemId, data, children)); }
protected void AddItemToTheDocument(BuilderLibraryTreeItem item) { // If this is the uxml file entry of the currently open file, don't allow // the user to instantiate it (infinite recursion) or re-open it. var listOfOpenDocuments = m_PaneWindow.document.openUXMLFiles; bool isCurrentDocumentOpen = listOfOpenDocuments.Any(doc => doc.uxmlFileName == item.name); if (isCurrentDocumentOpen) { return; } var newElement = item.makeVisualElementCallback?.Invoke(); if (newElement == null) { return; } var activeVTARootElement = m_DocumentRootElement.Query().Where(e => e.GetVisualTreeAsset() == m_PaneWindow.document.visualTreeAsset).First(); if (activeVTARootElement == null) { Debug.LogError("UI Builder has a bug. Could not find document root element for currently active open UXML document."); return; } activeVTARootElement.Add(newElement); if (item.makeElementAssetCallback == null) { BuilderAssetUtilities.AddElementToAsset(m_PaneWindow.document, newElement); } else { BuilderAssetUtilities.AddElementToAsset( m_PaneWindow.document, newElement, item.makeElementAssetCallback); } // TODO: ListView bug. Does not refresh selection pseudo states after a // call to Refresh(). m_Selection.NotifyOfHierarchyChange(); schedule.Execute(() => { m_Selection.Select(null, newElement); }).ExecuteLater(200); }
static void AddCategoriesToStack(BuilderLibraryTreeItem sourceCategory, List <BuilderLibraryTreeItem> categoryStack, string[] split) { if (categoryStack.Count > split.Length) { categoryStack.RemoveRange(split.Length, categoryStack.Count - split.Length); } string fullName = string.Empty; for (int i = 0; i < split.Length; ++i) { var part = split[i]; fullName += part; 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 BuilderLibraryTreeItem(part, null, null, null, null, new List <TreeViewItem <string> >(), null, fullName.GetHashCode()); if (categoryStack.Count == 0) { sourceCategory.AddChild(newCategory); } else { categoryStack[i - 1].AddChild(newCategory); } categoryStack.Add(newCategory); } } }
protected override bool StartDrag(VisualElement target, Vector2 mousePosition, VisualElement pill) { m_LibraryItem = target.GetProperty(BuilderConstants.LibraryItemLinkedManipulatorVEPropertyName) as BuilderLibraryTreeItem; if (m_LibraryItem == null) { return(false); } var isCurrentDocumentVisualTreeAsset = m_LibraryItem.sourceAsset == paneWindow.document.visualTreeAsset; if (isCurrentDocumentVisualTreeAsset) { return(false); } var madeElement = m_LibraryItem.makeVisualElementCallback?.Invoke(); if (madeElement == null) { return(false); } pill.Clear(); madeElement.AddToClassList(s_BeingDraggedClassName); pill.Add(madeElement); if (madeElement.GetType() == typeof(VisualElement)) { madeElement.AddToClassList(s_EmptyVisualElementClassName); } var overlay = new VisualElement(); overlay.name = s_OverlayName; overlay.AddToClassList(s_OverlayClassName); pill.Add(overlay); m_TooltipPreview.Disable(); return(true); }
protected void AddItemToTheDocument(BuilderLibraryTreeItem item) { // If this is the uxml file entry of the currently open file, don't allow // the user to instantiate it (infinite recursion) or re-open it. var listOfOpenDocuments = m_PaneWindow.document.openUXMLFiles; bool isCurrentDocumentOpen = listOfOpenDocuments.Any(doc => doc.uxmlFileName == item.Name); if (isCurrentDocumentOpen) { return; } var newElement = item.MakeVisualElementCallback?.Invoke(); if (newElement == null) { return; } m_DocumentElement.Add(newElement); if (item.MakeElementAssetCallback == null) { BuilderAssetUtilities.AddElementToAsset(m_PaneWindow.document, newElement); } else { BuilderAssetUtilities.AddElementToAsset( m_PaneWindow.document, newElement, item.MakeElementAssetCallback); } // TODO: ListView bug. Does not refresh selection pseudo states after a // call to Refresh(). m_Selection.NotifyOfHierarchyChange(); schedule.Execute(() => { m_Selection.Select(null, newElement); }).ExecuteLater(200); }
public LibraryPlainViewItem(BuilderLibraryTreeItem libraryTreeItem) { m_TreeItem = libraryTreeItem; var template = BuilderPackageUtilities.LoadAssetAtPath <VisualTreeAsset>(BuilderConstants.LibraryUIPath + "/BuilderLibraryPlainViewItem.uxml"); template.CloneTree(this); var styleSheet = BuilderPackageUtilities.LoadAssetAtPath <StyleSheet>(BuilderConstants.LibraryUIPath + "/BuilderLibraryPlainViewItem.uss"); styleSheets.Add(styleSheet); content = ElementAt(0); if (m_TreeItem == null) { content.AddToClassList(k_PlainViewNoHoverVariantUssClassName); content.Clear(); return; } this.Q <Label>().text = m_TreeItem.data; m_Icon = this.Q <VisualElement>("icon"); SetIcon(m_TreeItem.largeIcon); }
protected void LinkToTreeViewItem(VisualElement element, BuilderLibraryTreeItem libraryTreeItem) { element.userData = libraryTreeItem; element.SetProperty(BuilderConstants.LibraryItemLinkedManipulatorVEPropertyName, libraryTreeItem); }
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); }
public void ImportUxmlFromProject(BuilderLibraryTreeItem projectCategory, bool includePackages) { var assets = AssetDatabase.FindAllAssets(m_SearchFilter); var categoryStack = new List <BuilderLibraryTreeItem>(); foreach (var asset in assets) { var assetPath = AssetDatabase.GetAssetPath(asset.instanceID); var prettyPath = assetPath; prettyPath = Path.GetDirectoryName(prettyPath); prettyPath = prettyPath.ConvertSeparatorsToUnity(); if (prettyPath.StartsWith("Packages/") && !includePackages) { continue; } if (prettyPath.StartsWith(BuilderConstants.UIBuilderPackageRootPath)) { continue; } // Check to make sure the asset is actually writable. var packageInfo = PackageInfo.FindForAssetPath(assetPath); if (packageInfo != null && packageInfo.source != PackageSource.Embedded && packageInfo.source != PackageSource.Local) { continue; } // Anoter way to check the above. Leaving it here for references in case the above stops working. //AssetDatabase.GetAssetFolderInfo(assetPath, out bool isRoot, out bool isImmutable); //if (isImmutable) //continue; var split = prettyPath.Split('/'); AddCategoriesToStack(projectCategory, categoryStack, split); var vta = asset.pptrValue as VisualTreeAsset; var newItem = new BuilderLibraryTreeItem(asset.name + ".uxml", null, typeof(TemplateContainer), () => { if (vta == null) { return(null); } var tree = vta.CloneTree(); tree.SetProperty(BuilderConstants.LibraryItemLinkedTemplateContainerPathVEPropertyName, assetPath); tree.name = vta.name; return(tree); }, (inVta, inParent, ve) => { var vea = inVta.AddTemplateInstance(inParent, assetPath) as VisualElementAsset; vea.AddProperty("name", vta.name); ve.SetProperty(BuilderConstants.ElementLinkedInstancedVisualTreeAssetVEPropertyName, vta); return(vea); }, null, vta); newItem.SetIcon((Texture2D)EditorGUIUtility.IconContent("UxmlScript Icon").image); newItem.hasPreview = true; if (categoryStack.Count == 0) { projectCategory.AddChild(newItem); } else { categoryStack.Last().AddChild(newItem); } } }